mirror of
https://github.com/status-im/react-native.git
synced 2025-01-20 22:39:20 +00:00
91e5829419
Summary: Currently only scroll events are send through `sendEvent`, and all of them are can be coalesced. In future (further in the stack) touch events will go through there as well, but they won't support coalescing. In order to ensure js processes touch and scroll events in the same order as they were created, we will flush the coalesced events when we encounter one that cannot be coalesced. public ___ //This diff is part of a larger stack. For high level overview what's going on jump to D2884593.// Reviewed By: nicklockwood Differential Revision: D2884591 fb-gh-sync-id: a3d0e916843265ec57f16aad2f016a79764dcce8
182 lines
5.1 KiB
Objective-C
182 lines
5.1 KiB
Objective-C
/**
|
|
* 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 <UIKit/UIKit.h>
|
|
#import <XCTest/XCTest.h>
|
|
|
|
#import <OCMock/OCMock.h>
|
|
#import "RCTEventDispatcher.h"
|
|
|
|
@interface RCTTestEvent : NSObject <RCTEvent>
|
|
@property (atomic, assign, readwrite) BOOL canCoalesce;
|
|
@end
|
|
|
|
@implementation RCTTestEvent
|
|
{
|
|
NSDictionary<NSString *, id> *_body;
|
|
}
|
|
|
|
@synthesize viewTag = _viewTag;
|
|
@synthesize eventName = _eventName;
|
|
|
|
- (instancetype)initWithViewTag:(NSNumber *)viewTag eventName:(NSString *)eventName body:(NSDictionary<NSString *, id> *)body
|
|
{
|
|
if (self = [super init]) {
|
|
_viewTag = viewTag;
|
|
_eventName = eventName;
|
|
_body = body;
|
|
_canCoalesce = YES;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (id<RCTEvent>)coalesceWithEvent:(id<RCTEvent>)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<NSString *, id> *_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<RCTFrameUpdateObserver>)_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<RCTFrameUpdateObserver>)_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<RCTFrameUpdateObserver>)_eventDispatcher didUpdateFrame:nil];
|
|
|
|
[_bridge verify];
|
|
}
|
|
|
|
@end
|