Libxml2XCTests.m   [plain text]

//
// Libxml2XCTests.m
// Libxml2XCTests
//
// Created by David Kilzer on 2017/01/09.
//

#import <dlfcn.h>
#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>

typedef int (MainFunction)(int, char**);

@interface Libxml2XCTests : XCTestCase
@property (readonly) NSBundle *bundle;
- (int)_invokeMainForTestCommand:(NSString *)command;
- (void)_printOutputFile:(NSString *)file;
@end

@implementation Libxml2XCTests

- (NSBundle *)bundle
{
static NSBundle *bundle = nil;
if (!bundle) {
bundle = [NSBundle bundleForClass:[self class]];
XCTAssertNotNil(bundle, @"bundle should not be nil for class %@", [self class]);
}
return bundle;
}

- (int)_invokeMainForTestCommand:(NSString *)command
{
// Get path to binary from NSBundle.
NSString *resourceName = [NSString stringWithFormat:@"libxml2_%@.dylib", command];
NSString *binaryPath = [self.bundle pathForResource:resourceName ofType:nil];
XCTAssertNotNil(binaryPath, @"binaryPath should not be nil for %@", resourceName);

// Use dyld to load 'main' symbol from binary.
void* binary = dlopen([binaryPath UTF8String], RTLD_LAZY|RTLD_LOCAL);
XCTAssertTrue(!!binary, @"binary should not be NULL loading path (%s): %s", [binaryPath UTF8String], dlerror());
MainFunction *binaryMain = (MainFunction *)dlsym(binary, "main");
XCTAssertTrue(!!binaryMain, @"binaryMain should not be NULL: %s", dlerror());

// Change current directory so that the binary can find its test files.
NSString *binaryDirectory = [binaryPath stringByDeletingLastPathComponent];
BOOL success = [[NSFileManager defaultManager] changeCurrentDirectoryPath:binaryDirectory];
XCTAssertTrue(success, @"Could not change directory to: %@", binaryDirectory);

// Call 'main' to run the test.
char* argv[] = { (char*)[command UTF8String] };
return binaryMain(1, argv);
}

- (void)_printOutputFile:(NSString *)file
{
NSString *path = [[self.bundle resourcePath] stringByAppendingPathComponent:file];
fprintf(stderr, "\n------- Begin %s\n", [file UTF8String]);
NSError *error;
fprintf(stderr, "%s", [[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error] UTF8String]);
fprintf(stderr, "------- End %s\n\n", [file UTF8String]);
if (error)
fprintf(stderr, "\n------- Error loading %s: %s\n\n", [path UTF8String], [[error description] UTF8String]);
}

- (void)test_runtest
{
NSString *command = @"runtest";
int result = [self _invokeMainForTestCommand:command];
XCTAssertTrue(result == 0, @"%@`main() returned no errors", command);
}

- (void)test_runxmlconf
{
NSString *command = @"runxmlconf";
int result = [self _invokeMainForTestCommand:command];
XCTAssertTrue(result == 0, @"%@`main() returned no errors", command);
[self _printOutputFile:@"runxmlconf.log"];
}

- (void)test_testapi
{
NSString *command = @"testapi";
int result = [self _invokeMainForTestCommand:command];
XCTAssertTrue(result == 0, @"%@`main() returned no errors", command);
[self _printOutputFile:@"test.out"];
}

- (void)test_testchar
{
NSString *command = @"testchar";
int result = [self _invokeMainForTestCommand:command];
XCTAssertTrue(result == 0, @"%@`main() returned no errors", command);
}

- (void)test_testdict
{
NSString *command = @"testdict";
int result = [self _invokeMainForTestCommand:command];
XCTAssertTrue(result == 0, @"%@`main() returned no errors", command);
}

- (void)test_testrecurse
{
NSString *command = @"testrecurse";
int result = [self _invokeMainForTestCommand:command];
XCTAssertTrue(result == 0, @"%@`main() returned no errors", command);
}

@end