Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update comments and outdated variable names
Browse files Browse the repository at this point in the history
bartekpacia committed Sep 12, 2023
1 parent a20e1f3 commit 1b44a73
Showing 5 changed files with 125 additions and 124 deletions.
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ class DartTestGroupExtensionsTest {
}

// when
val dartTestFiles = dartTestGroup.listTestsFlat()
val dartTests = dartTestGroup.listTestsFlat()

// then
assertContentEquals(
@@ -48,7 +48,7 @@ class DartTestGroupExtensionsTest {
dartTestCase { name = "open_app_test open maps" },
dartTestCase { name = "webview_test interacts with the LeanCode website in a webview" },
),
dartTestFiles,
dartTests,
)
}

@@ -96,7 +96,7 @@ class DartTestGroupExtensionsTest {
}

// when
val dartTestFiles = rootDartTestGroup.listTestsFlat()
val dartTests = rootDartTestGroup.listTestsFlat()

// then
assertContentEquals(
@@ -112,7 +112,7 @@ class DartTestGroupExtensionsTest {
dartTestCase { name = "open_app_test open maps" },
dartTestCase { name = "open_app_test open browser" },
),
dartTestFiles,
dartTests,
)
}
}
2 changes: 0 additions & 2 deletions packages/patrol/ios/Classes/PatrolAppServiceClient.swift
Original file line number Diff line number Diff line change
@@ -41,8 +41,6 @@ import NIO
let request = Patrol_Empty()
let response = try await client.listDartTests(request)

NSLog("RAW: Got tests: \(response.group)")

return response.group.listTestsFlat(parentGroupName: "").map {
$0.name
}
196 changes: 98 additions & 98 deletions packages/patrol/ios/Classes/PatrolIntegrationTestRunner.h
Original file line number Diff line number Diff line change
@@ -9,102 +9,102 @@

// For every Flutter dart test, dynamically generate an Objective-C method mirroring the test results
// so it is reported as a native XCTest run result.
#define PATROL_INTEGRATION_TEST_IOS_RUNNER(__test_class) \
@interface __test_class : XCTestCase \
@end \
\
@implementation __test_class \
\
+(NSArray<NSInvocation *> *)testInvocations { \
/* Start native automation gRPC server */ \
PatrolServer *server = [[PatrolServer alloc] init]; \
[server startWithCompletionHandler:^(NSError * err) { \
NSLog(@"Server loop done, error: %@", err); \
}]; \
\
/* Create a client for PatrolAppService, which lets us list and run Dart tests */ \
__block PatrolAppServiceClient *appServiceClient = [[PatrolAppServiceClient alloc] init]; \
\
/* Allow the Local Network permission required by Dart Observatory */ \
XCUIApplication *springboard = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.springboard"]; \
XCUIElementQuery *systemAlerts = springboard.alerts; \
if (systemAlerts.buttons[@"Allow"].exists) { \
[systemAlerts.buttons[@"Allow"] tap]; \
} \
\
/* Run the app for the first time to gather Dart tests */ \
[[[XCUIApplication alloc] init] launch]; \
\
/* Spin the runloop waiting until the app reports that it is ready to report Dart tests */ \
while (!server.appReady) { \
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]; \
} \
\
__block NSArray<NSString *> *dartTestFiles = NULL; \
[appServiceClient \
listDartTestsWithCompletionHandler:^(NSArray<NSString *> *_Nullable dartTests, NSError *_Nullable err) { \
if (err != NULL) { \
NSLog(@"listDartTests(): failed, err: %@", err); \
} \
\
dartTestFiles = dartTests; \
}]; \
\
/* Spin the runloop waiting until the app reports the Dart tests it contains */ \
while (!dartTestFiles) { \
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]; \
} \
\
NSLog(@"Got %lu Dart tests: %@", dartTestFiles.count, dartTestFiles); \
\
NSMutableArray<NSInvocation *> *invocations = [[NSMutableArray alloc] init]; \
\
/** \
* Once Dart tests are available, we: \
* \
* Step 1. Dynamically add test case methods that request execution of an individual Dart test file. \
* \
* Step 2. Create invocations to the generated methods and return them \
*/ \
\
for (NSString * dartTestFile in dartTestFiles) { \
/* Step 1 - dynamically create test cases */ \
\
IMP implementation = imp_implementationWithBlock(^(id _self) { \
[[[XCUIApplication alloc] init] launch]; \
\
__block RunDartTestResponse *response = NULL; \
[appServiceClient runDartTestWithName:dartTestFile \
completionHandler:^(RunDartTestResponse *_Nullable r, NSError *_Nullable err) { \
if (err != NULL) { \
NSLog(@"runDartTestWithName(%@): failed, err: %@", dartTestFile, err); \
} \
\
response = r; \
}]; \
\
/* Wait until Dart test finishes */ \
while (!response) { \
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]; \
} \
\
XCTAssertTrue(response.passed, @"%@", response.details); \
}); \
NSString *selectorName = [PatrolUtils createMethodNameFromPatrolGeneratedGroup:dartTestFile]; \
SEL selector = NSSelectorFromString(selectorName); \
class_addMethod(self, selector, implementation, "v@:"); \
\
/* Step 2 – create invocations to the dynamically created methods */ \
NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; \
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; \
invocation.selector = selector; \
\
NSLog(@"RunnerUITests.testInvocations(): selectorName = %@, signature: %@", selectorName, signature); \
\
[invocations addObject:invocation]; \
} \
\
return invocations; \
} \
\
#define PATROL_INTEGRATION_TEST_IOS_RUNNER(__test_class) \
@interface __test_class : XCTestCase \
@end \
\
@implementation __test_class \
\
+(NSArray<NSInvocation *> *)testInvocations { \
/* Start native automation gRPC server */ \
PatrolServer *server = [[PatrolServer alloc] init]; \
[server startWithCompletionHandler:^(NSError * err) { \
NSLog(@"Server loop done, error: %@", err); \
}]; \
\
/* Create a client for PatrolAppService, which lets us list and run Dart tests */ \
__block PatrolAppServiceClient *appServiceClient = [[PatrolAppServiceClient alloc] init]; \
\
/* Allow the Local Network permission required by Dart Observatory */ \
XCUIApplication *springboard = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.springboard"]; \
XCUIElementQuery *systemAlerts = springboard.alerts; \
if (systemAlerts.buttons[@"Allow"].exists) { \
[systemAlerts.buttons[@"Allow"] tap]; \
} \
\
/* Run the app for the first time to gather Dart tests */ \
[[[XCUIApplication alloc] init] launch]; \
\
/* Spin the runloop waiting until the app reports that it is ready to report Dart tests */ \
while (!server.appReady) { \
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]; \
} \
\
__block NSArray<NSString *> *dartTests = NULL; \
[appServiceClient \
listDartTestsWithCompletionHandler:^(NSArray<NSString *> *_Nullable tests, NSError *_Nullable err) { \
if (err != NULL) { \
NSLog(@"listDartTests(): failed, err: %@", err); \
} \
\
dartTests = tests; \
}]; \
\
/* Spin the runloop waiting until the app reports the Dart tests it contains */ \
while (!dartTests) { \
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]; \
} \
\
NSLog(@"Got %lu Dart tests: %@", dartTests.count, dartTests); \
\
NSMutableArray<NSInvocation *> *invocations = [[NSMutableArray alloc] init]; \
\
/** \
* Once Dart tests are available, we: \
* \
* Step 1. Dynamically add test case methods that request execution of an individual Dart test file. \
* \
* Step 2. Create invocations to the generated methods and return them \
*/ \
\
for (NSString * dartTest in dartTests) { \
/* Step 1 - dynamically create test cases */ \
\
IMP implementation = imp_implementationWithBlock(^(id _self) { \
[[[XCUIApplication alloc] init] launch]; \
\
__block RunDartTestResponse *response = NULL; \
[appServiceClient runDartTestWithName:dartTest \
completionHandler:^(RunDartTestResponse *_Nullable r, NSError *_Nullable err) { \
if (err != NULL) { \
NSLog(@"runDartTestWithName(%@): failed, err: %@", dartTest, err); \
} \
\
response = r; \
}]; \
\
/* Wait until Dart test finishes */ \
while (!response) { \
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]; \
} \
\
XCTAssertTrue(response.passed, @"%@", response.details); \
}); \
NSString *selectorName = [PatrolUtils createMethodNameFromPatrolGeneratedGroup:dartTest]; \
SEL selector = NSSelectorFromString(selectorName); \
class_addMethod(self, selector, implementation, "v@:"); \
\
/* Step 2 – create invocations to the dynamically created methods */ \
NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; \
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; \
invocation.selector = selector; \
\
NSLog(@"RunnerUITests.testInvocations(): selectorName = %@, signature: %@", selectorName, signature); \
\
[invocations addObject:invocation]; \
} \
\
return invocations; \
} \
\
@end\
9 changes: 4 additions & 5 deletions packages/patrol/lib/src/binding.dart
Original file line number Diff line number Diff line change
@@ -46,11 +46,10 @@ class PatrolBinding extends IntegrationTestWidgetsFlutterBinding {
PatrolBinding() {
final oldTestExceptionReporter = reportTestException;
reportTestException = (details, testDescription) {
final currentDartTestFile = _currentDartTest;
if (currentDartTestFile != null) {
final currentDartTest = _currentDartTest;
if (currentDartTest != null) {
assert(!constants.hotRestartEnabled);
_testResults[currentDartTestFile] =
Failure(testDescription, '$details');
_testResults[currentDartTest] = Failure(testDescription, '$details');
}
oldTestExceptionReporter(details, testDescription);
};
@@ -175,7 +174,7 @@ class PatrolBinding extends IntegrationTestWidgetsFlutterBinding {
void attachRootWidget(Widget rootWidget) {
assert(
(_currentDartTest != null) != (constants.hotRestartEnabled),
'_currentDartTestFile can be null if and only if Hot Restart is enabled',
'_currentDartTest can be null if and only if Hot Restart is enabled',
);

const testLabelEnabled = bool.fromEnvironment('PATROL_TEST_LABEL_ENABLED');
34 changes: 19 additions & 15 deletions packages/patrol/lib/src/native/patrol_app_service.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
//TODO: Use a logger instead of print

// ignore_for_file: avoid_print
// TODO: Use a logger instead of print

import 'dart:async';
import 'dart:io' as io;

import 'package:grpc/grpc.dart';
import 'package:patrol/src/common.dart';
import 'package:patrol/src/native/contracts/contracts.pbgrpc.dart';

const _port = 8082;
@@ -84,30 +86,32 @@ class PatrolAppService extends PatrolAppServiceBase {
);
}

/// Returns when the native side requests execution of a Dart test file.
/// Returns when the native side requests execution of a Dart test. If the
/// native side requsted execution of [dartTest], returns true. Otherwise
/// returns false.
///
/// The native side requests execution by RPC-ing [runDartTest] and providing
/// name of a Dart test file.
/// It's used inside of [patrolTest] to halt execution of test body until
/// [runDartTest] is called.
///
/// Returns true if the native side requsted execution of [dartTestFile].
/// Returns false otherwise.
Future<bool> waitForExecutionRequest(String dartTestFile) async {
print('PatrolAppService: registered "$dartTestFile"');

final requestedDartTestFile = await testExecutionRequested;
if (requestedDartTestFile != dartTestFile) {
// If the requested Dart test file is not the one we're waiting for now,
// it means that dartTestFile was already executed. Return false so that
/// The native side requests execution by RPC-ing [runDartTest] and providing
/// name of a Dart test that it wants to currently execute [dartTest].
Future<bool> waitForExecutionRequest(String dartTest) async {
print('PatrolAppService: registered "$dartTest"');

final requestedDartTest = await testExecutionRequested;
if (requestedDartTest != dartTest) {
// If the requested Dart test is not the one we're waiting for now,
// it means that dartTest was already executed. Return false so that
// callers can skip the already executed test.

print(
'PatrolAppService: registered test "$dartTestFile" was not matched by requested test "$requestedDartTestFile"',
'PatrolAppService: registered test "$dartTest" was not matched by requested test "$requestedDartTest"',
);

return false;
}

print('PatrolAppService: requested execution of test "$dartTestFile"');
print('PatrolAppService: requested execution of test "$dartTest"');

return true;
}

0 comments on commit 1b44a73

Please sign in to comment.