Custom logic blocks for RCTTestRunner's runTest: method

Reviewed By: majak

Differential Revision: D2626497

fb-gh-sync-id: c78e3b47be4ee192e899594bd05b13521af7172e
This commit is contained in:
Pawel Sienkowski 2015-11-13 08:34:26 -08:00 committed by facebook-github-bot-3
parent 760a2fc79a
commit 3a42661b47
4 changed files with 43 additions and 16 deletions

View File

@ -12,7 +12,6 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import <XCTest/XCTest.h> #import <XCTest/XCTest.h>
#import "RCTSparseArray.h" #import "RCTSparseArray.h"

View File

@ -47,7 +47,7 @@
[_runner runTest:_cmd [_runner runTest:_cmd
module:@"IntegrationTestHarnessTest" module:@"IntegrationTestHarnessTest"
initialProps:@{@"waitOneFrame": @YES} initialProps:@{@"waitOneFrame": @YES}
expectErrorBlock:nil]; configurationBlock:nil];
} }
- (void)testTheTester_ExpectError - (void)testTheTester_ExpectError
@ -55,6 +55,7 @@
[_runner runTest:_cmd [_runner runTest:_cmd
module:@"IntegrationTestHarnessTest" module:@"IntegrationTestHarnessTest"
initialProps:@{@"shouldThrow": @YES} initialProps:@{@"shouldThrow": @YES}
configurationBlock:nil
expectErrorRegex:@"because shouldThrow"]; expectErrorRegex:@"because shouldThrow"];
} }

View File

@ -24,6 +24,8 @@
@protocol RCTBridgeModule; @protocol RCTBridgeModule;
@class RCTRootView;
@interface RCTTestRunner : NSObject @interface RCTTestRunner : NSObject
@property (nonatomic, assign) BOOL recordMode; @property (nonatomic, assign) BOOL recordMode;
@ -59,26 +61,42 @@
/** /**
* Same as runTest:, but allows for passing initialProps for providing mock data * Same as runTest:, but allows for passing initialProps for providing mock data
* or requesting different behaviors, and expectErrorRegex verifies that the * or requesting different behaviors, configurationBlock provides arbitrary logic for the hosting
* error you expected was thrown. * root view manipulation.
* *
* @param test Selector of the test, usually just `_cmd`. * @param test Selector of the test, usually just `_cmd`.
* @param moduleName Name of the JS component as registered by `AppRegistry.registerComponent` in JS. * @param moduleName Name of the JS component as registered by `AppRegistry.registerComponent` in JS.
* @param initialProps props that are passed into the component when rendered. * @param initialProps props that are passed into the component when rendered.
* @param expectErrorRegex A regex that must match the error thrown. If no error is thrown, the test fails. * @param configurationBlock A block that takes the hosting root view and performs arbitrary manipulation after its creation.
*/ */
- (void)runTest:(SEL)test module:(NSString *)moduleName initialProps:(NSDictionary *)initialProps expectErrorRegex:(NSString *)expectErrorRegex;
- (void)runTest:(SEL)test module:(NSString *)moduleName initialProps:(NSDictionary *)initialProps configurationBlock:(void(^)(RCTRootView *rootView))configurationBlock;
/** /**
* Same as runTest:, but allows for passing initialProps for providing mock data * Same as runTest:, but allows for passing initialProps for providing mock data
* or requesting different behaviors, and expectErrorBlock provides arbitrary * or requesting different behaviors, configurationBlock provides arbitrary logic for the hosting
* root view manipulation, and expectErrorRegex verifies that the error you expected was thrown.
*
* @param test Selector of the test, usually just `_cmd`.
* @param moduleName Name of the JS component as registered by `AppRegistry.registerComponent` in JS.
* @param initialProps props that are passed into the component when rendered.
* @param configurationBlock A block that takes the hosting root view and performs arbitrary manipulation after its creation.
* @param expectErrorRegex A regex that must match the error thrown. If no error is thrown, the test fails.
*/
- (void)runTest:(SEL)test module:(NSString *)moduleName initialProps:(NSDictionary *)initialProps configurationBlock:(void(^)(RCTRootView *rootView))configurationBlock expectErrorRegex:(NSString *)expectErrorRegex;
/**
* Same as runTest:, but allows for passing initialProps for providing mock data
* or requesting different behaviors, configurationBlock provides arbitrary logic for the hosting
* root view manipulation, and expectErrorBlock provides arbitrary
* logic for processing errors (nil will cause any error to fail the test). * logic for processing errors (nil will cause any error to fail the test).
* *
* @param test Selector of the test, usually just `_cmd`. * @param test Selector of the test, usually just `_cmd`.
* @param moduleName Name of the JS component as registered by `AppRegistry.registerComponent` in JS. * @param moduleName Name of the JS component as registered by `AppRegistry.registerComponent` in JS.
* @param initialProps props that are passed into the component when rendered. * @param initialProps props that are passed into the component when rendered.
* @param configurationBlock A block that takes the hosting root view and performs arbitrary manipulation after its creation.
* @param expectErrorBlock A block that takes the error message and returns NO to fail the test. * @param expectErrorBlock A block that takes the error message and returns NO to fail the test.
*/ */
- (void)runTest:(SEL)test module:(NSString *)moduleName initialProps:(NSDictionary *)initialProps expectErrorBlock:(BOOL(^)(NSString *error))expectErrorBlock; - (void)runTest:(SEL)test module:(NSString *)moduleName initialProps:(NSDictionary *)initialProps configurationBlock:(void(^)(RCTRootView *rootView))configurationBlock expectErrorBlock:(BOOL(^)(NSString *error))expectErrorBlock;
@end @end

View File

@ -68,19 +68,24 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (void)runTest:(SEL)test module:(NSString *)moduleName - (void)runTest:(SEL)test module:(NSString *)moduleName
{ {
[self runTest:test module:moduleName initialProps:nil expectErrorBlock:nil]; [self runTest:test module:moduleName initialProps:nil configurationBlock:nil expectErrorBlock:nil];
} }
- (void)runTest:(SEL)test module:(NSString *)moduleName - (void)runTest:(SEL)test module:(NSString *)moduleName initialProps:(NSDictionary *)initialProps configurationBlock:(void(^)(RCTRootView *rootView))configurationBlock
initialProps:(NSDictionary *)initialProps expectErrorRegex:(NSString *)errorRegex
{ {
[self runTest:test module:moduleName initialProps:initialProps expectErrorBlock:^BOOL(NSString *error){ [self runTest:test module:moduleName initialProps:initialProps configurationBlock:configurationBlock expectErrorBlock:nil];
return [error rangeOfString:errorRegex options:NSRegularExpressionSearch].location != NSNotFound;
}];
} }
- (void)runTest:(SEL)test module:(NSString *)moduleName - (void)runTest:(SEL)test module:(NSString *)moduleName initialProps:(NSDictionary *)initialProps configurationBlock:(void(^)(RCTRootView *rootView))configurationBlock expectErrorRegex:(NSString *)errorRegex
initialProps:(NSDictionary *)initialProps expectErrorBlock:(BOOL(^)(NSString *error))expectErrorBlock {
BOOL(^expectErrorBlock)(NSString *error) = ^BOOL(NSString *error){
return [error rangeOfString:errorRegex options:NSRegularExpressionSearch].location != NSNotFound;
};
[self runTest:test module:moduleName initialProps:initialProps configurationBlock:configurationBlock expectErrorBlock:expectErrorBlock];
}
- (void)runTest:(SEL)test module:(NSString *)moduleName initialProps:(NSDictionary *)initialProps configurationBlock:(void(^)(RCTRootView *rootView))configurationBlock expectErrorBlock:(BOOL(^)(NSString *error))expectErrorBlock
{ {
__weak id weakJSContext; __weak id weakJSContext;
@ -110,6 +115,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
vc.view = [UIView new]; vc.view = [UIView new];
[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
if (configurationBlock) {
configurationBlock(rootView);
}
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:kTestTimeoutSeconds]; NSDate *date = [NSDate dateWithTimeIntervalSinceNow:kTestTimeoutSeconds];
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]];