diff -r 984743875355 Classes-MacOSX/UI/GHTestAppDelegate.h --- a/Classes-MacOSX/UI/GHTestAppDelegate.h Sat Mar 14 16:17:23 2009 -0400 +++ b/Classes-MacOSX/UI/GHTestAppDelegate.h Sat Mar 14 17:15:58 2009 -0400 @@ -36,4 +36,12 @@ - (void)runTests; +/*! + @brief Run tests matching the given identifier. + @param testIdentifier A string of the form or + This method parses out the given test identifier and either: + (a) runs all tests in a named TestCase, or (c) runs the named test in the named TestCase. + */ +- (void)runTestsWithIdentifier:(NSString *)testIndentifier; + @end diff -r 984743875355 Classes-MacOSX/UI/GHTestAppDelegate.m --- a/Classes-MacOSX/UI/GHTestAppDelegate.m Sat Mar 14 16:17:23 2009 -0400 +++ b/Classes-MacOSX/UI/GHTestAppDelegate.m Sat Mar 14 17:15:58 2009 -0400 @@ -38,7 +38,39 @@ - (void)awakeFromNib { windowController_ = [[GHTestWindowController alloc] init]; [windowController_ showWindow:nil]; - [self runTests]; + + NSArray *arguments = [[NSProcessInfo processInfo] arguments]; + + switch ( [arguments count] ) { + + case 3:{ + // testapp -Test or testapp -Test All + NSString * arg = [arguments objectAtIndex:1]; + if ( [@"-Test" isEqualToString:arg] ) { + // Parse the argument, which can take three forms: @"All", testCase, or testCase/testName + NSString *argValue = [arguments objectAtIndex:2]; + if ( [@"All" isEqualToString:argValue] ) { + [self runTests]; + } else { + [self runTestsWithIdentifier:argValue]; + } + } else { + // When specified, the second argument must be "-Test". If it isn't + // then that's a BadThing(tm). Handle this condition by running all tests. + [self runTests]; + } + break; + } + + default: + [self runTests]; + break; + } +} + +- (void)runTestsWithIdentifier:(NSString *)testIndentifier; +{ + [NSThread detachNewThreadSelector:@selector(_runTestsWithIdentifier:) toTarget:self withObject:testIndentifier]; } - (void)runTests { @@ -54,6 +86,26 @@ //runner.raiseExceptions = YES; [runner run]; + [pool release]; +} + +- (void)_runTestsWithIdentifier:(NSString *)testIdentifier { + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + // Create a suite with tests identified by the test identifier. + GHTestSuite *suite = [GHTestSuite suiteWithTestsWithIdentifier:testIdentifier]; + + // Create a runner for the suite and let it rip + + GHTestRunner *runner = [[[GHTestRunner runnerForSuite:suite] retain] autorelease]; + runner.delegate = self; + runner.delegateOnMainThread = YES; + // To allow exceptions to raise into the debugger, uncomment below + //runner.raiseExceptions = YES; + + [runner run]; + [pool release]; } diff -r 984743875355 Classes/GHTestSuite.h --- a/Classes/GHTestSuite.h Sat Mar 14 16:17:23 2009 -0400 +++ b/Classes/GHTestSuite.h Sat Mar 14 17:15:58 2009 -0400 @@ -65,4 +65,6 @@ // If flatten is YES, returns a test suite with all tests grouped here. + (GHTestSuite *)allTests:(BOOL)flatten; +// Will load the identified tests; identifier is of the form or ++ (GHTestSuite *) suiteWithTestsWithIdentifier:(NSString *)testIdentifier; @end diff -r 984743875355 Classes/GHTestSuite.m --- a/Classes/GHTestSuite.m Sat Mar 14 16:17:23 2009 -0400 +++ b/Classes/GHTestSuite.m Sat Mar 14 17:15:58 2009 -0400 @@ -56,7 +56,69 @@ [allTests addTestCase:testCase]; } } - return [allTests autorelease];; + return [allTests autorelease]; } ++ (GHTestSuite *) suiteWithTestsWithIdentifier:(NSString *)testIdentifier; +{ + GHTestSuite *testSuite = nil; + + // testIdentifier can take two forms: + // 1. testCase/testName, specifying an individual test + // 2. testCase, which should be interpreted as 'run all tests in testCase' + + id testCase = nil; + NSString *individualTestName = nil; + + // Parse the testIdentifier into a TestCase instance and an optional test name. + { + NSArray *parts = [testIdentifier componentsSeparatedByString:@"/"]; + assert( [parts count] > 0 ); + + // Tease out the test case Class and the individual test name. + + Class testCaseClass = NSClassFromString([parts objectAtIndex:0]); + if ( [parts count] == 2 ) { + individualTestName = [parts objectAtIndex:1]; + } + + // Instantiate the named TestCase. + if (isTestFixture(testCaseClass) || isSenTestCaseClass(testCaseClass) || isGTMTestCaseClass(testCaseClass)) { + testCase = [[testCaseClass alloc] init]; + } + } + + if ( testCase ) { + + // Add tests from the test case + testSuite = [[[GHTestSuite alloc] initWithName:@"Tests" delegate:nil] autorelease]; + + if ( ! individualTestName ) { + + // Add all tests from the testCase + [testSuite addTestsFromTestCase:testCase]; + + } else { + + // Just add the identified test. + NSArray *tests = [GHTestUtils loadTestsFromTarget:testCase]; + for (GHTest *test in tests) { + if ( [testIdentifier isEqualToString:[test identifier]] ) { + [test setDelegate:testSuite]; + [testSuite addTest:test]; + break; + } + } + } + + } else { + + // We got bad input; the named test case doesn't exist. + // Handle this error condition by creating a test suite with all availables tests. + + testSuite = [GHTestSuite allTests]; + } + + return testSuite; +} @end