mirror of
https://github.com/status-im/react-native.git
synced 2025-02-24 15:18:10 +00:00
Fixed test flakiness due to a race condition with RCTRedBox
Summary: The test runner relied on checking the current error message in the RCTRedbox, which is a singleton (yay, shared mutable state!). This lead to some tests that worked individually but failed when run together due to error messages in RCTRedBox left over from previous tests. I've replaced the call to -[RCTRedBox currentErrorMessage] by injecting a custom logging function to intercept the errors at source, which is a much more reliable solution.
This commit is contained in:
parent
b18d73b568
commit
26c4be62c8
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#import "FBSnapshotTestController.h"
|
#import "FBSnapshotTestController.h"
|
||||||
#import "RCTAssert.h"
|
#import "RCTAssert.h"
|
||||||
#import "RCTRedBox.h"
|
#import "RCTLog.h"
|
||||||
#import "RCTRootView.h"
|
#import "RCTRootView.h"
|
||||||
#import "RCTTestModule.h"
|
#import "RCTTestModule.h"
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
@ -83,6 +83,13 @@ RCT_NOT_IMPLEMENTED(-init)
|
|||||||
- (void)runTest:(SEL)test module:(NSString *)moduleName
|
- (void)runTest:(SEL)test module:(NSString *)moduleName
|
||||||
initialProps:(NSDictionary *)initialProps expectErrorBlock:(BOOL(^)(NSString *error))expectErrorBlock
|
initialProps:(NSDictionary *)initialProps expectErrorBlock:(BOOL(^)(NSString *error))expectErrorBlock
|
||||||
{
|
{
|
||||||
|
__block NSString *error = nil;
|
||||||
|
RCTSetLogFunction(^(RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message) {
|
||||||
|
if (level >= RCTLogLevelError) {
|
||||||
|
error = message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_scriptURL
|
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_scriptURL
|
||||||
moduleProvider:_moduleProvider
|
moduleProvider:_moduleProvider
|
||||||
launchOptions:nil];
|
launchOptions:nil];
|
||||||
@ -102,20 +109,19 @@ RCT_NOT_IMPLEMENTED(-init)
|
|||||||
[vc.view addSubview:rootView]; // Add as subview so it doesn't get resized
|
[vc.view addSubview:rootView]; // Add as subview so it doesn't get resized
|
||||||
|
|
||||||
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
|
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
|
||||||
NSString *error = [[RCTRedBox sharedInstance] currentErrorMessage];
|
|
||||||
while ([date timeIntervalSinceNow] > 0 && testModule.status == RCTTestStatusPending && error == nil) {
|
while ([date timeIntervalSinceNow] > 0 && testModule.status == RCTTestStatusPending && error == nil) {
|
||||||
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||||
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||||
error = [[RCTRedBox sharedInstance] currentErrorMessage];
|
|
||||||
}
|
}
|
||||||
[rootView removeFromSuperview];
|
[rootView removeFromSuperview];
|
||||||
|
|
||||||
|
RCTSetLogFunction(RCTDefaultLogFunction);
|
||||||
|
|
||||||
NSArray *nonLayoutSubviews = [vc.view.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id subview, NSDictionary *bindings) {
|
NSArray *nonLayoutSubviews = [vc.view.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id subview, NSDictionary *bindings) {
|
||||||
return ![NSStringFromClass([subview class]) isEqualToString:@"_UILayoutGuide"];
|
return ![NSStringFromClass([subview class]) isEqualToString:@"_UILayoutGuide"];
|
||||||
}]];
|
}]];
|
||||||
RCTAssert(nonLayoutSubviews.count == 0, @"There shouldn't be any other views: %@", nonLayoutSubviews);
|
RCTAssert(nonLayoutSubviews.count == 0, @"There shouldn't be any other views: %@", nonLayoutSubviews);
|
||||||
|
|
||||||
[[RCTRedBox sharedInstance] dismiss];
|
|
||||||
if (expectErrorBlock) {
|
if (expectErrorBlock) {
|
||||||
RCTAssert(expectErrorBlock(error), @"Expected an error but nothing matched.");
|
RCTAssert(expectErrorBlock(error), @"Expected an error but nothing matched.");
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user