Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use new recordIssue: API #315

Merged
merged 4 commits into from
Apr 25, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 78 additions & 57 deletions UnitTesting/GTMGoogleTestRunner.mm
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,11 @@ @interface XCTSkippedTestContext : NSObject

- (id)initWithExplanation:(NSString *)explanation
evaluatedExpression:(NSString *)evaluatedExpression
message:(NSString*)message
sourceCodeContext:(XCTSourceCodeContext*)sourceCodeContext;
message:(NSString *)message
sourceCodeContext:(XCTSourceCodeContext *)sourceCodeContext;

@end


using ::testing::EmptyTestEventListener;
using ::testing::TestCase;
using ::testing::TestEventListener;
Expand All @@ -91,14 +90,20 @@ @interface GTMGoogleTestRunner : XCTestCase {
}

// We need Xcode 11.4 or better to support test skipping.
#define IS_XCODE_11_4_OR_BETTER (__IPHONE_OS_VERSION_MAX_ALLOWED >= 130400 \
|| __MAC_OS_X_VERSION_MAX_ALLOWED >= 101504)
#define IS_XCODE_11_4_OR_BETTER \
(__IPHONE_OS_VERSION_MAX_ALLOWED >= 130400 || \
__MAC_OS_X_VERSION_MAX_ALLOWED >= 101504)

// We need Xcode 11.4 or better to support XCTIssue.
#define IS_XCODE_12_0_OR_BETTER \
(__IPHONE_OS_VERSION_MAX_ALLOWED >= 130700 || \
__MAC_OS_X_VERSION_MAX_ALLOWED >= 101504)

#if IS_XCODE_11_4_OR_BETTER

// If a test has been skipped this will be set with an exception describing
// the skipped test.
@property (nonatomic) _XCTSkipFailureException *skipException;
@property(nonatomic) _XCTSkipFailureException *skipException;
#endif

// The name for a test is the GoogleTest name which is "TestCase.Test"
Expand All @@ -118,49 +123,66 @@ - (id)initWithName:(NSString *)testName;
virtual ~GoogleTestPrinter() {}

virtual void OnTestPartResult(const TestPartResult &test_part_result) {
if (!test_part_result.passed()) {
const char *file_name = test_part_result.file_name();
NSString *file = @(file_name ? file_name : "<file name unavailable>");
int line = test_part_result.line_number();
NSString *summary = @(test_part_result.summary());

// gtest likes to give multi-line summaries. These don't look good in
// the Xcode UI, so we clean them up.
NSString *oneLineSummary =
[summary stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
BOOL expected = test_part_result.nonfatally_failed();
if (test_part_result.passed()) {
return;
}

const char *file_name = test_part_result.file_name();
NSString *file = @(file_name ? file_name : "<file name unavailable>");
int line = test_part_result.line_number();
NSString *summary = @(test_part_result.summary());

// gtest likes to give multi-line summaries. These don't look good in
// the Xcode UI, so we clean them up.
NSString *oneLineSummary =
[summary stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
BOOL expected = test_part_result.nonfatally_failed();
#if IS_XCODE_11_4_OR_BETTER
eytanbiala marked this conversation as resolved.
Show resolved Hide resolved
if (test_part_result.skipped()) {
// Test skipping works differently than other test failures in XCTest in
// that it is done via exceptions. We can't throw the exception from
// here though because it will be caught by the GUnit test
// infrastructure and reported as an error. So we record all of the data
// we need, and then throw the exception in -runGoogleTest once we are
// above the GUnit exception handling code.
XCTSourceCodeLocation *location =
[[XCTSourceCodeLocation alloc] initWithFilePath:file
lineNumber:line];
XCTSourceCodeContext *codeContext =
[[XCTSourceCodeContext alloc] initWithLocation:location];
XCTSkippedTestContext *skippedContext =
[[XCTSkippedTestContext alloc] initWithExplanation:oneLineSummary
evaluatedExpression:nil
message:nil
sourceCodeContext:codeContext];
NSDictionary *userInfo =
@{@"XCTestErrorUserInfoKeySkippedTestContext" : skippedContext};
test_case_.skipException =
[[_XCTSkipFailureException alloc] initWithName:@"_XCTSkipFailureException"
reason:@"Test skipped"
userInfo:userInfo];
return;
}
#endif
[test_case_ recordFailureWithDescription:oneLineSummary
inFile:file
atLine:line
expected:expected];
XCTSourceCodeLocation *location =
[[XCTSourceCodeLocation alloc] initWithFilePath:file lineNumber:line];
XCTSourceCodeContext *codeContext =
[[XCTSourceCodeContext alloc] initWithLocation:location];

if (test_part_result.skipped()) {
// Test skipping works differently than other test failures in XCTest in
// that it is done via exceptions. We can't throw the exception from
// here though because it will be caught by the GUnit test
// infrastructure and reported as an error. So we record all of the data
// we need, and then throw the exception in -runGoogleTest once we are
// above the GUnit exception handling code.
XCTSkippedTestContext *skippedContext =
[[XCTSkippedTestContext alloc] initWithExplanation:oneLineSummary
evaluatedExpression:nil
message:nil
sourceCodeContext:codeContext];
NSDictionary *userInfo =
@{@"XCTestErrorUserInfoKeySkippedTestContext" : skippedContext};
test_case_.skipException = [[_XCTSkipFailureException alloc]
initWithName:@"_XCTSkipFailureException"
reason:@"Test skipped"
userInfo:userInfo];
return;
} else {
#if IS_XCODE_12_0_OR_BETTER
XCTIssue *issue = [[XCTIssue alloc]
initWithType:expected ? XCTIssueTypeAssertionFailure
: XCTIssueTypeUncaughtException
compactDescription:oneLineSummary
detailedDescription:summary
sourceCodeContext:codeContext
associatedError:nil
attachments:@[]];
[test_case_ recordIssue:issue];
return;
#endif // IS_XCODE_12_0_OR_BETTER
}

#else // IS_XCODE_11_4_OR_BETTER
[test_case_ recordFailureWithDescription:oneLineSummary
inFile:file
atLine:line
expected:expected];
#endif
}

private:
Expand All @@ -169,9 +191,8 @@ virtual void OnTestPartResult(const TestPartResult &test_part_result) {

NSString *SelectorNameFromGTestName(NSString *testName) {
NSRange dot = [testName rangeOfString:@"."];
return [NSString stringWithFormat:@"%@::%@",
[testName substringToIndex:dot.location],
[testName substringFromIndex:dot.location + 1]];
return [NSString stringWithFormat:@"%@::%@", [testName substringToIndex:dot.location],
[testName substringFromIndex:dot.location + 1]];
}

} // namespace
Expand All @@ -186,7 +207,7 @@ + (void)initGoogleTest {
int argc = (int)arguments.count;
char **argv = static_cast<char **>(alloca((sizeof(char *) * (argc + 1))));
for (int index = 0; index < argc; index++) {
argv[index] = const_cast<char *> ([arguments[index] UTF8String]);
argv[index] = const_cast<char *>([arguments[index] UTF8String]);
}
argv[argc] = NULL;

Expand All @@ -208,8 +229,8 @@ + (id)defaultTestSuite {
[result addTest:subSuite];
for (int j = 0; j < total_test_count; ++j) {
const TestInfo *test_info = test_case->GetTestInfo(j);
NSString *testName = [NSString stringWithFormat:@"%s.%s",
test_case->name(), test_info->name()];
NSString *testName = [NSString
stringWithFormat:@"%s.%s", test_case->name(), test_info->name()];
XCTestCase *xcTest = [[self alloc] initWithName:testName];
[subSuite addTest:xcTest];
}
Expand Down Expand Up @@ -246,16 +267,16 @@ - (id)initWithName:(NSString *)testName {
- (NSString *)name {
// An XCTest name must be "-[foo bar]" or it won't be parsed properly.
NSRange dot = [testName_ rangeOfString:@"."];
return [NSString stringWithFormat:@"-[%@ %@]",
[testName_ substringToIndex:dot.location],
[testName_ substringFromIndex:dot.location + 1]];
return [NSString
stringWithFormat:@"-[%@ %@]", [testName_ substringToIndex:dot.location],
[testName_ substringFromIndex:dot.location + 1]];
}

- (void)runGoogleTest {
[GTMGoogleTestRunner initGoogleTest];

// Gets hold of the event listener list.
TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
TestEventListeners &listeners = UnitTest::GetInstance()->listeners();

// Adds a listener to the end.
GoogleTestPrinter printer = GoogleTestPrinter(self);
Expand Down