├── .gitignore ├── .travis.yml ├── Documentation └── Templates │ └── menu.html ├── FrameworkSource ├── English.lproj │ └── UKTestHandler.strings ├── Info.plist ├── UKRunner.h ├── UKRunner.m ├── UKTest.h ├── UKTestHandler.h ├── UKTestHandler.m └── UnitKit.h ├── GNUmakefile ├── INSTALL.Cocoa.md ├── INSTALL.GNUstep.md ├── LICENSE ├── NEWS.md ├── NOTICE ├── Package ├── Description.plist ├── Info.plist └── Resources │ ├── License.txt │ ├── Readme.txt │ └── Welcome.txt ├── README.md ├── TODO.md ├── TestSource ├── TestBundle │ ├── GNUmakefile │ ├── Info.plist │ ├── TestOne.h │ ├── TestOne.m │ ├── TestThree.h │ ├── TestThree.m │ ├── TestTwo.h │ └── TestTwo.m ├── TestFramework │ ├── GNUmakefile │ ├── Info.plist │ ├── TestClass.h │ └── TestClass.m └── TestUnitKit │ ├── GNUmakefile │ ├── Info.plist │ ├── TestObject.h │ ├── TestObject.m │ ├── UKRunnerTests.h │ ├── UKRunnerTests.m │ ├── UKTestFileNames.h │ ├── UKTestFileNames.m │ ├── UKTestFramework.h │ ├── UKTestFramework.m │ ├── UKTestLineNumbers.h │ ├── UKTestLineNumbers.m │ ├── UKTestMacros.h │ ├── UKTestMacros.m │ ├── UKTestMessages.h │ └── UKTestMessages.m ├── ToolSource ├── GNUmakefile └── main.m ├── UnitKit.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ ├── TestUnitKit (iOS).xcscheme │ ├── TestUnitKit.xcscheme │ └── ukrun.xcscheme ├── Xcode3Integration ├── FileTemplates │ ├── TemplateInfo.plist │ ├── class.h │ └── class.m └── TargetTemplates │ └── UnitKitBundle.trgttmpl ├── XcodeIntegration ├── File Templates │ └── Cocoa │ │ └── Objective-C UnitKit test case class.xctemplate │ │ ├── NSObject │ │ └── ___FILEBASENAME___.m │ │ ├── TemplateIcon.icns │ │ └── TemplateInfo.plist └── Project Templates │ └── Mac │ └── Other │ └── UnitKit Testing Bundle.xctemplate │ ├── TemplateIcon.icns │ └── TemplateInfo.plist ├── compilerflags.preamble ├── iOSCompatibility ├── Default-568h@2x.png ├── Info.plist └── main.m ├── test-linux.sh └── test-macosx.sh /.gitignore: -------------------------------------------------------------------------------- 1 | xcuserdata 2 | *.xcworkspace 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | notifications: 2 | email: 3 | recipients: 4 | - etoile-testbuild@gna.org 5 | 6 | language: generic 7 | compiler: gcc 8 | os: 9 | - linux 10 | - osx 11 | 12 | matrix: 13 | include: 14 | - os: linux 15 | dist: trusty 16 | sudo: required 17 | language: cpp 18 | env: TEST_BUILD=gnustep 19 | addons: 20 | apt: 21 | sources: 22 | - llvm-toolchain-trusty-3.8 23 | packages: 24 | - clang-3.8 25 | - os: osx 26 | language: objective-c 27 | env: TEST_BUILD=mac 28 | exclude: 29 | - language: generic 30 | 31 | script: 32 | - if [[ $TRAVIS_OS_NAME == 'osx' && $TEST_BUILD == 'mac' ]]; then ./test-macosx.sh; fi 33 | - if [[ $TRAVIS_OS_NAME == 'linux' && $TEST_BUILD == 'gnustep' ]]; then ./test-linux.sh; fi 34 | -------------------------------------------------------------------------------- /Documentation/Templates/menu.html: -------------------------------------------------------------------------------- 1 |

2 | 8 | 9 |

Main

10 | 14 | 15 | 24 | 25 |

C Symbols

26 | 32 | 33 |

Classes

34 | 35 | 36 |

Protocols

37 | 38 | 39 |

Categories

40 | 41 | -------------------------------------------------------------------------------- /FrameworkSource/English.lproj/UKTestHandler.strings: -------------------------------------------------------------------------------- 1 | /* 2 | This source is part of UnitKit, a unit test framework for Mac OS X 3 | development. You can find more information about UnitKit at: 4 | 5 | http://x180.net/Code/UnitKit 6 | 7 | Copyright (c)2004 James Duncan Davidson 8 | 9 | Contributions by Michael Milvich 10 | 11 | Licensed under the Apache License, Version 2.0 (the "License"); 12 | you may not use this file except in compliance with the License. 13 | You may obtain a copy of the License at 14 | 15 | http://www.apache.org/licenses/LICENSE-2.0 16 | 17 | Unless required by applicable law or agreed to in writing, software 18 | distributed under the License is distributed on an "AS IS" BASIS, 19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | See the License for the specific language governing permissions and 21 | limitations under the License. 22 | 23 | The use of the Apache License does not indicate that this project is 24 | affiliated with the Apache Software Foundation. 25 | */ 26 | 27 | errExceptionOnInit = "Error in [%@:init]. Uncaught exception %@. Stack trace: %@"; 28 | errExceptionInTestMethod = "Error in test [%@:%@]. Uncaught exception %@. Stack trace: %@"; 29 | errExceptionOnRelease = "Error in test [%@:dealloc]. Uncaught exception %@. Stack trace: %@"; 30 | 31 | msgUKPass = "Passed"; 32 | msgUKFail = "Failed"; 33 | msgUKTrue.pass = "Passed, expected true, got true"; 34 | msgUKTrue.fail = "Failed, expected true, got false"; 35 | msgUKFalse.pass = "Passed, expected false, got false"; 36 | msgUKFalse.fail = "Failed, expected false, got true"; 37 | msgUKNil.pass = "Passed, expected nil, got nil"; 38 | msgUKNil.fail = "Failed, expected nil, got %@"; 39 | msgUKNotNil.pass = "Passed, expected not nil, got %@"; 40 | msgUKNotNil.fail = "Failed, expected not nil, got nil"; 41 | msgUKIntsEqual.pass = "Passed, expected %lld, got %lld"; 42 | msgUKIntsEqual.fail = "Failed, expected %lld, got %lld"; 43 | msgUKIntsNotEqual.pass = "Passed, didn't expect %lld, got %lld"; 44 | msgUKIntsNotEqual.fail = "Failed, didn't expect %lld, got %lld"; 45 | msgUKFloatsEqual.pass = "Passed, expected %f-%f, got %f"; 46 | msgUKFloatsEqual.fail = "Failed, expected %f-%f, got %f"; 47 | msgUKFloatsNotEqual.pass = "Passed, didn't expect %f-%f, got %f"; 48 | msgUKFloatsNotEqual.fail = "Failed, didn't expect %f-%f, got %f"; 49 | msgUKObjectKindOf.pass = "Passed, expected %@, got %@"; 50 | msgUKObjectKindOf.fail = "Failed, expected %@, got %@"; 51 | msgUKObjectsEqual.pass = "Passed, expected %@, got %@"; 52 | msgUKObjectsEqual.fail = "Failed, expected %@, got %@"; 53 | msgUKObjectsNotEqual.pass = "Passed, didn't expect %@, got %@"; 54 | msgUKObjectsNotEqual.fail = "Failed, didn't expect %@, got %@"; 55 | msgUKObjectsSame.pass = "Passed, expected %@, got %@"; 56 | msgUKObjectsSame.fail = "Failed, expected %@, got %@"; 57 | msgUKObjectsNotSame.pass = "Passed, didn't expect %@, got %@"; 58 | msgUKObjectsNotSame.fail = "Failed, didn't expect %@, got %@"; 59 | msgUKStringsEqual.pass = "Passed, expected %@, got %@"; 60 | msgUKStringsEqual.fail = "Failed, expected %@, got %@"; 61 | msgUKStringsNotEqual.pass = "Passed, didn't expect %@, got %@"; 62 | msgUKStringsNotEqual.fail = "Failed, didn't expect %@, got %@"; 63 | msgUKStringContains.pass = "Passed, %@ contains %@"; 64 | msgUKStringContains.fail = "Failed, %@ doesn't contain %@"; 65 | msgUKStringDoesNotContain.pass = "Passed, expected %@ to contain %@"; 66 | msgUKStringDoesNotContain.fail = "Failed, %@ contains %@"; 67 | 68 | msgUKExceptionRaised.pass = "Passed, raised exception %@"; 69 | msgUKExecptionRaised.fail = "Failed, an exception was not raised"; 70 | msgUKExceptionNotRaised.pass = "Passed, no exception was raised"; 71 | msgUKExceptionNotRaised.fail = "Failed, an exeception %@ was raised"; 72 | msgUKSpecificNSExceptionRaised.pass = "Passed, an NSException of type %@ was raised"; 73 | msgUKSpecificNSExceptionRaised.fail = "Failed, an NSException of type %@ was not raised, got %@"; 74 | msgUKSpecificNSExceptionRaised.failNotNSException = "Failed, expected NSException, got %@"; 75 | msgUKRaisesSpecificClass.pass = "Passed, %@ was raised"; 76 | msgUKRaisesSpecificClass.fail = "Failed, expected %@ to be raised, got %@"; 77 | 78 | -------------------------------------------------------------------------------- /FrameworkSource/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | org.etoile-project.UnitKit 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | FMWK 15 | CFBundleShortVersionString 16 | 1.5 17 | CFBundleSignature 18 | ???? 19 | NSHumanReadableCopyright 20 | Copyright © 2014 Étoilé. All rights reserved. 21 | 22 | 23 | -------------------------------------------------------------------------------- /FrameworkSource/UKRunner.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) 2004 James Duncan Davidson, Nicolas Roard, Quentin Mathe, Christopher Armstrong, Eric Wasylishen 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | 24 | /** 25 | * @abstract UKTestRunner runs the test suite(s) and reports the results. 26 | * 27 | * Usually you are not expected to use UKRunner directly to run a test suite, 28 | * but to use ukrun that will ask UKRunner to do it with +runTests. 29 | * 30 | * @section Test Bundle Loading and Argument Parsing 31 | * 32 | * UKRunner will parse arguments from the command-line bound to 33 | * -[UKTestHandler isQuiet] and -[UKRunner classRegex], and can load one or 34 | * multiple test bundles, either passed among the arguments or to 35 | * -runTestsInBundle:principalClass: (if you use the API directly instead of 36 | * ukrun). 37 | * 38 | * @section Collecting Test Classes 39 | * 40 | * For each test bundle, UKRunner collects test classes marked with UKTest. 41 | * If you don't use a test bundle, test classes can be passed explicitly with 42 | * -runTestsWithClassNames:principalClass:. 43 | * 44 | * If -classRegex is set, not all the test classes passed to UKRunner API will 45 | * be run, but just the subset whose name matches the regex. 46 | * 47 | * @section Executing Test Methods 48 | * 49 | * A test method is a method prefixed with test e.g. -testSometing. 50 | * 51 | * For each class marked with UKTest and each test method in this class (this 52 | * also includes all the inherited test methods up to the superclass that 53 | * conforms to UKTest), UKRunner will create an instance and invoke the test 54 | * method, then release the instance, then create a new instance for the next 55 | * test method, and so on. For details, see -runTests:onInstance:ofClass:. 56 | * 57 | * UKRunner also supports test class methods e.g. +testSomething. 58 | * 59 | * The test methods are executed in their alphabetical order. 60 | * 61 | * @section Notifications 62 | * 63 | * Each time methods -runTestsWithClassNames:principalClass: and 64 | * -runTestsInBundle:principalClass: are invoked, the runner calls 65 | * +willRunTestSuite and +didRunTestSuite on the principal class, and runs the 66 | * test suite between them. 67 | * 68 | * For common use cases, see +[NSObject willRunTestSuite]. 69 | */ 70 | @interface UKRunner : NSObject 71 | 72 | 73 | /** @taskunit Settings */ 74 | 75 | 76 | /** 77 | * Returns the regex string used to match classes to be tested (among the 78 | * classes that conforms to UKTest). 79 | * 80 | * This is useful to run a test suite subset. For example, just a single class 81 | * TestB, a class list TestA|TestB|TestN or a 82 | * pattern-based list Test*Persistency. 83 | * 84 | * -classRegex is initialized to the value of the argument -c present 85 | * in the ukrun arguments. 86 | * 87 | * See also -setClassRegex:. 88 | */ 89 | @property (nonatomic, copy) NSString *classRegex; 90 | /** 91 | * Sets the regex string used to match classes to be tested (among the 92 | * classes that conforms to UKTest). 93 | * 94 | * See also -classRegex. 95 | */ 96 | /** 97 | * Only run tests in the class with this name. If set, classRegex is ignored. 98 | */ 99 | @property (nonatomic, copy) NSString *className; 100 | /** 101 | * Only run test methods matching this regex. 102 | */ 103 | @property (nonatomic, copy) NSString *methodRegex; 104 | /** 105 | * Only run test methods with this name. If set, methodRegex is ignored. 106 | */ 107 | @property (nonatomic, copy) NSString *methodName; 108 | 109 | 110 | /** @taskunit Tool Support */ 111 | 112 | 113 | /** 114 | * Creates a new runner and uses it to run the tests based on the command-line 115 | * arguments. 116 | * 117 | * For all the test bundles collected (or provided as arguments), this method 118 | * uses -runTestsInBundleAtPath:currrentDirectory: to run the tests contained 119 | * in each one. When all test bundles have been run, -reportTestResults is 120 | * called to output the combined results. 121 | * 122 | * ukrun main() creates an autorelease pool, and uses this method to run the 123 | * tests. 124 | */ 125 | + (int)runTests; 126 | /** 127 | * Loads the given test bundle, and runs all its tests. 128 | * 129 | * If the bundle path is not an absolute path, the method searches the test 130 | * bundles to load in the given directory (the current directory, when +runTests 131 | * is used). 132 | */ 133 | - (void)runTestsInBundleAtPath: (NSString *)bundlePath 134 | currentDirectory: (NSString *)cwd; 135 | 136 | 137 | /** @taskunit Running Tests */ 138 | 139 | 140 | /** 141 | * Runs all the tests in the given test bundle. 142 | * 143 | * This method behaves the same than -runTestsWithClassNames:principalClass:, 144 | * with the test bundle principal class as the test suite principal class. 145 | */ 146 | - (void)runTestsInBundle: (NSBundle *)bundle; 147 | /** 148 | * Runs all the tests in the tested classes. 149 | * 150 | * For test related configuration, +willRunTestSuite and +didRunTestSuite 151 | * are sent to the principal class, see NSObject(UKPrincipalClassNotifications). 152 | * 153 | * If testedClasses is nil, then it is the same than passing all the test 154 | * classes present in the main bundle. 155 | * 156 | * This method and -runTestsInBundle: represents a test suite invocation. 157 | */ 158 | - (void)runTestsWithClassNames: (NSArray *)testClasses 159 | principalClass: (Class)principalClass; 160 | /** 161 | * Runs the test methods against a test instance or class object. 162 | * 163 | * testMethods contains the method names to execute on the test object or class 164 | * object. If instance is YES, testMethods must contain instance methods, 165 | * otherwise it must contain class methods (to be called directly on the test 166 | * class). 167 | * 168 | * For each method in the list, the test object will be initialized with -init, 169 | * and the test method called on it, then the test object will be released (and 170 | * usually deallocated). 171 | * 172 | * If there is a problem with the test object initialization or release (once 173 | * the test method returns the control), an uncaught exception will be reported 174 | * and the test execution on this test object will end (other test methods 175 | * are skipped). 176 | * 177 | * If there is an exception while running a test method, an uncaught exception 178 | * will be reported and execution will move on to the next test method. 179 | */ 180 | - (void)runTests: (NSArray *)testMethods 181 | onInstance: (BOOL)instance 182 | ofClass: (Class)testClass; 183 | 184 | 185 | /** @taskunit Test Reporting */ 186 | 187 | 188 | /** 189 | * Logs a summary that reports the current run results: 190 | * 191 | * 192 | * how many test classes and test methods were executed 193 | * how many tests failed and passed 194 | * how many uncaught exceptions occurred 195 | * 196 | * 197 | * If no tests failed and no uncaught exceptions occured, returns 0 to indicate 198 | * success, otherwise returns -1. 199 | */ 200 | - (int)reportTestResults; 201 | 202 | @end 203 | 204 | /** 205 | * @abstract Test suite related notifications. 206 | * 207 | * These delegate methods can be implemented in the principal class. See the 208 | * Notifications section in UKRunner class description. 209 | */ 210 | @interface NSObject (UKPrincipalClassNotifications) 211 | /** 212 | * Tells the principal class that the test suite is about to start. 213 | * 214 | * The principal class comes from the test bundle Info.plist, 215 | * -runTestsInBundle:principalClass: or -runTestsWithClassNames:principalClass: 216 | * (if these last two methods are called directly without using ukrun). 217 | * 218 | * You can implement this method to set up some global state (e.g. create a 219 | * NSApp object with +[NSApplication sharedApplication]) or test configuration. 220 | * 221 | * See also +didRunTestSuite. 222 | */ 223 | + (void)willRunTestSuite; 224 | /** 225 | * Tells the principal class that the test suite is about to end. 226 | * 227 | * You can implement this method to reset some global state or test 228 | * configuration, previously adjusted in +willRunTestSuite, and also to report 229 | * additional test results (e.g. benchmark results). 230 | * 231 | * See also +willRunTestSuite. 232 | */ 233 | + (void)didRunTestSuite; 234 | 235 | @end 236 | 237 | /** 238 | * Returns all the test classes present in the given bundle, and sorted by name. 239 | * 240 | * To be a test class, a class (or its superclass) must conform to UKTest 241 | * protocol. 242 | */ 243 | NSArray *UKTestClassNamesFromBundle(NSBundle *bundle); 244 | /** 245 | * Returns all the test method names sorted by name, for the given class. 246 | * 247 | * All the superclass methods are collected (until the root class is reached). 248 | */ 249 | NSArray *UKTestMethodNamesFromClass(Class c); 250 | -------------------------------------------------------------------------------- /FrameworkSource/UKRunner.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson, Nicolas Roard, Quentin Mathe, Christopher Armstrong, Eric Wasylishen 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "UKRunner.h" 23 | #import "UKTest.h" 24 | #import "UKTestHandler.h" 25 | 26 | #include 27 | 28 | // NOTE: From EtoileFoundation/Macros.h 29 | #define INVALIDARG_EXCEPTION_TEST(arg, condition) do { \ 30 | if (NO == (condition)) \ 31 | { \ 32 | [NSException raise: NSInvalidArgumentException format: @"For %@, %s " \ 33 | "must respect %s", NSStringFromSelector(_cmd), #arg , #condition]; \ 34 | } \ 35 | } while (0); 36 | #define NILARG_EXCEPTION_TEST(arg) do { \ 37 | if (nil == arg) \ 38 | { \ 39 | [NSException raise: NSInvalidArgumentException format: @"For %@, " \ 40 | "%s must not be nil", NSStringFromSelector(_cmd), #arg]; \ 41 | } \ 42 | } while (0); 43 | 44 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 45 | 46 | @implementation UKRunner 47 | { 48 | int _testClassesRun; 49 | int _testMethodsRun; 50 | BOOL _releasing; 51 | } 52 | 53 | #pragma mark - Localization Support 54 | 55 | + (NSString *)localizedString: (NSString *)key 56 | { 57 | NSBundle *bundle = [NSBundle bundleForClass: [self class]]; 58 | return NSLocalizedStringFromTableInBundle(key, @"UKRunner", bundle, @""); 59 | } 60 | 61 | + (NSString *)displayStringForException: (id)exc 62 | { 63 | if ([exc isKindOfClass: [NSException class]]) 64 | { 65 | return [NSString stringWithFormat: @"NSException: %@ %@", 66 | [exc name], [exc reason]]; 67 | } 68 | else 69 | { 70 | return NSStringFromClass([exc class]); 71 | } 72 | } 73 | 74 | /** 75 | * For now, we still support -classRegex as an alias to -c. 76 | * 77 | * This options read with NSUserDefaults is overwritten by 78 | * -parseArgumentsWithCurrentDirectory:. This NSUserDefaults use should probably 79 | * be removed at some point. 80 | */ 81 | - (NSString *)stringFromArgumentDomainForKey: (NSString *)key 82 | { 83 | NSDictionary *argumentDomain = [[NSUserDefaults standardUserDefaults] 84 | volatileDomainForName: NSArgumentDomain]; 85 | return argumentDomain[key]; 86 | } 87 | 88 | - (instancetype)init 89 | { 90 | self = [super init]; 91 | if (self == nil) 92 | return nil; 93 | 94 | _classRegex = [self stringFromArgumentDomainForKey: @"c"]; 95 | if (nil == _classRegex) 96 | { 97 | _classRegex = [self stringFromArgumentDomainForKey: @"classRegex"]; 98 | } 99 | _className = [self stringFromArgumentDomainForKey: @"className"]; 100 | _methodRegex = [self stringFromArgumentDomainForKey: @"methodRegex"]; 101 | _methodName = [self stringFromArgumentDomainForKey: @"methodName"]; 102 | 103 | return self; 104 | } 105 | 106 | #pragma mark - Loading Test Bundles 107 | 108 | - (id)loadBundleAtPath: (NSString *)bundlePath 109 | { 110 | NSBundle *testBundle = [NSBundle bundleWithPath: bundlePath]; 111 | 112 | if (testBundle == nil) 113 | { 114 | NSLog(@"\n == Test bundle '%@' could not be found ==\n", bundlePath.lastPathComponent); 115 | return nil; 116 | } 117 | 118 | if (![bundlePath.pathExtension isEqual: [self testBundleExtension]]) 119 | { 120 | NSLog(@"\n == Directory '%@' is not a test bundle ==\n", bundlePath.lastPathComponent); 121 | } 122 | 123 | NSError *error = nil; 124 | 125 | /* For Mac OS X (10.8), the test bundle info.plist must declare a principal 126 | class, to prevent +load from instantiating NSApp. */ 127 | #ifdef GNUSTEP 128 | if (![testBundle load]) 129 | #else 130 | if (![testBundle loadAndReturnError: &error]) 131 | #endif 132 | { 133 | NSLog(@"\n == Test bundle could not be loaded: %@ ==\n", error.description); 134 | return nil; 135 | } 136 | return testBundle; 137 | } 138 | 139 | - (NSString *)testBundleExtension 140 | { 141 | return @"bundle"; 142 | } 143 | 144 | - (NSArray *)bundlePathsInCurrentDirectory: (NSString *)cwd 145 | { 146 | NSError *error = nil; 147 | NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath: cwd 148 | error: &error]; 149 | NSAssert(error == nil, [error description]); 150 | 151 | return [files filteredArrayUsingPredicate: 152 | [NSPredicate predicateWithFormat: @"pathExtension == %@", 153 | [self testBundleExtension]]]; 154 | } 155 | 156 | - (NSArray *)bundlePathsFromArgumentsAndCurrentDirectory: (NSString *)cwd 157 | { 158 | NSArray *bundlePaths = [self parseArgumentsWithCurrentDirectory: cwd]; 159 | NSAssert(bundlePaths != nil, @""); 160 | BOOL hadBundleInArgument = (bundlePaths.count > 0); 161 | 162 | if (hadBundleInArgument) 163 | return bundlePaths; 164 | 165 | /* If no bundles is specified, then just collect every bundle in this folder */ 166 | return [self bundlePathsInCurrentDirectory: cwd]; 167 | } 168 | 169 | #pragma mark - Tool Support 170 | 171 | + (int)runTests 172 | { 173 | NSString *version = [NSBundle bundleForClass: self].infoDictionary[@"CFBundleShortVersionString"]; 174 | int result = 0; 175 | 176 | NSLog(@"UnitKit version %@ (Etoile)", version); 177 | 178 | @autoreleasepool 179 | { 180 | UKRunner *runner = [[UKRunner alloc] init]; 181 | NSString *cwd = [NSFileManager defaultManager].currentDirectoryPath; 182 | 183 | for (NSString *bundlePath in [runner bundlePathsFromArgumentsAndCurrentDirectory: cwd]) 184 | { 185 | [runner runTestsInBundleAtPath: bundlePath 186 | currentDirectory: cwd]; 187 | } 188 | 189 | result = [runner reportTestResults]; 190 | } 191 | return result; 192 | } 193 | 194 | /** 195 | * Don't try to parse options without value e.g. -q with NSUserDefaults, 196 | * otherwise the option will be ignored or its value set to the next argument. 197 | * For example, the NSArgumentDomain dictionary would be: 198 | * 199 | * 'ukrun -q' => { } 200 | * 'ukrun -q TestBundle.bundle' => { -q = TestBundle.bundle } 201 | */ 202 | - (NSArray *)parseArgumentsWithCurrentDirectory: (NSString *)cwd 203 | { 204 | NSArray *args = [NSProcessInfo processInfo].arguments; 205 | NSMutableArray *bundlePaths = [NSMutableArray array]; 206 | BOOL noOptions = (args.count <= 1); 207 | NSSet *paramOptions = [NSSet setWithObjects: 208 | @"-c", 209 | @"-classRegex", 210 | @"-className", 211 | @"-methodRegex", 212 | @"-methodName", 213 | nil]; 214 | 215 | if (noOptions) 216 | return bundlePaths; 217 | 218 | for (int i = 1; i < args.count; i++) 219 | { 220 | NSString *arg = args[i]; 221 | 222 | /* We parse all supported options to skip them and process the test 223 | bundle list at the end */ 224 | if ([arg isEqualToString: @"-q"]) 225 | { 226 | [[UKTestHandler handler] setQuiet: YES]; 227 | } 228 | else if ([paramOptions containsObject: arg]) 229 | { 230 | i++; 231 | 232 | if (i >= args.count || [args[i] hasPrefix: @"-"]) 233 | { 234 | NSLog(@"%@ argument must be followed by a parameter", arg); 235 | exit(-1); 236 | } 237 | NSString *param = args[i]; 238 | 239 | if ([arg isEqualToString: @"-c"] || [arg isEqualToString: @"-classRegex"]) 240 | { 241 | _classRegex = param; 242 | } 243 | else if ([arg isEqualToString: @"-className"]) 244 | { 245 | _className = param; 246 | } 247 | else if ([arg isEqualToString: @"-methodRegex"]) 248 | { 249 | _methodRegex = param; 250 | } 251 | else if ([arg isEqualToString: @"-methodName"]) 252 | { 253 | _methodName = param; 254 | } 255 | } 256 | else 257 | { 258 | [bundlePaths addObject: args[i]]; 259 | } 260 | } 261 | return bundlePaths; 262 | } 263 | 264 | - (void)runTestsInBundleAtPath: (NSString *)bundlePath 265 | currentDirectory: (NSString *)cwd 266 | { 267 | bundlePath = bundlePath.stringByExpandingTildeInPath; 268 | 269 | if (![bundlePath isAbsolutePath]) 270 | { 271 | bundlePath = [cwd stringByAppendingPathComponent: bundlePath]; 272 | bundlePath = bundlePath.stringByStandardizingPath; 273 | } 274 | 275 | NSLog(@"Looking for bundle at path: %@", bundlePath); 276 | 277 | @autoreleasepool 278 | { 279 | NSBundle *testBundle = [self loadBundleAtPath: bundlePath]; 280 | 281 | if (testBundle != nil) 282 | { 283 | [self runTestsInBundle: testBundle]; 284 | } 285 | } 286 | } 287 | 288 | #pragma mark - Running Test Method 289 | 290 | - (void)internalRunTest: (NSTimer *)timer 291 | { 292 | NSDictionary *testParameters = timer.userInfo; 293 | NSString *testMethodName = testParameters[@"TestSelector"]; 294 | SEL testSel = NSSelectorFromString(testMethodName); 295 | id testObject = testParameters[@"TestObject"]; 296 | Class testClass = testParameters[@"TestClass"]; 297 | 298 | // N.B.: On GNUstep, NSTimer ignores exceptions 299 | // so they wouldn't reach the @catch block in -runTests:onInstance:ofClass:, 300 | // so we need this @try/@catch block here 301 | @try 302 | { 303 | [testObject performSelector: testSel]; 304 | } 305 | @catch (NSException *exception) 306 | { 307 | [[UKTestHandler handler] reportException: exception 308 | inClass: testClass 309 | hint: testMethodName]; 310 | } 311 | } 312 | 313 | - (void)runTest: (SEL)testSelector onObject: (id)testObject class: (Class)testClass 314 | { 315 | NSLog(@"=== [%@ %@] ===", [testObject class], NSStringFromSelector(testSelector)); 316 | 317 | NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 318 | NSDictionary *testParams = @{@"TestObject": testObject, 319 | @"TestSelector": NSStringFromSelector(testSelector), 320 | @"TestClass": testClass}; 321 | NSTimer *runTimer = [NSTimer scheduledTimerWithTimeInterval: 0 322 | target: self 323 | selector: @selector(internalRunTest:) 324 | userInfo: testParams 325 | repeats: NO]; 326 | 327 | while ([runTimer isValid]) 328 | { 329 | // NOTE: nil, [NSDate date], time intervals such as 0, 0.0000001 or 330 | // LDBL_EPSILON don't work on GNUstep. 331 | // 332 | // 0.000001 was working on GNUstep, but it resulted in freezing 333 | // when debugging with Valgrind! Using 0.001 fixed that, 334 | // but it suggests that gnustep-base might be broken 335 | #ifdef GNUSTEP 336 | NSTimeInterval interval = 0.001; 337 | #else 338 | NSTimeInterval interval = 0; 339 | #endif 340 | [runLoop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: interval]]; 341 | } 342 | } 343 | 344 | #pragma mark - Running Tests 345 | 346 | - (void)runTests: (NSArray *)testMethods onInstance: (BOOL)instance ofClass: (Class)testClass 347 | { 348 | for (NSString *testMethodName in testMethods) 349 | { 350 | _testMethodsRun++; 351 | 352 | @try 353 | { 354 | @autoreleasepool 355 | { 356 | [self runTestNamed: testMethodName 357 | onInstance: instance 358 | ofClass: testClass]; 359 | } 360 | } 361 | @catch (NSException *exception) 362 | { 363 | id hint = (_releasing ? @"errExceptionOnRelease" : nil); 364 | 365 | [[UKTestHandler handler] reportException: exception 366 | inClass: testClass 367 | hint: hint]; 368 | } 369 | _releasing = NO; 370 | } 371 | } 372 | 373 | - (void)runTestNamed: (NSString *)testMethodName 374 | onInstance: (BOOL)instance 375 | ofClass: (Class)testClass 376 | { 377 | id object = nil; 378 | 379 | // Create the object to test 380 | 381 | if (instance) 382 | { 383 | @try 384 | { 385 | object = [[testClass alloc] init]; 386 | } 387 | @catch (NSException *exception) 388 | { 389 | [[UKTestHandler handler] reportException: exception 390 | inClass: testClass 391 | hint: @"errExceptionOnInit"]; 392 | } 393 | 394 | // N.B.: If -init throws an exception or returns nil, we don't 395 | // attempt to run any more methods on this class 396 | if (object == nil) 397 | return; 398 | } 399 | else 400 | { 401 | object = testClass; 402 | } 403 | 404 | // Run the test method 405 | 406 | @try 407 | { 408 | SEL testSel = NSSelectorFromString(testMethodName); 409 | 410 | /* This pool makes easier to separate autorelease issues between: 411 | - test method 412 | - test object configuration due to -init and -dealloc 413 | 414 | For testing CoreObject, this also ensures all autoreleased 415 | objects in relation to a db are deallocated before closing 416 | the db connection in -dealloc (see TestCommon.h in CoreObject 417 | for details) */ 418 | @autoreleasepool 419 | { 420 | [self runTest: testSel onObject: object class: testClass]; 421 | } 422 | } 423 | @catch (NSException *exception) 424 | { 425 | [[UKTestHandler handler] reportException: exception 426 | inClass: testClass 427 | hint: testMethodName]; 428 | } 429 | 430 | // Release the object 431 | 432 | if (instance) 433 | { 434 | @try 435 | { 436 | _releasing = YES; 437 | object = nil; 438 | } 439 | @catch (NSException *exception) 440 | { 441 | // N.B.: With ARC, we usually catch dealloc exception later in the 442 | // caller, when the enclosing autorelease pool goes away. 443 | [[UKTestHandler handler] reportException: exception 444 | inClass: [object class] 445 | hint: @"errExceptionOnRelease"]; 446 | } 447 | } 448 | } 449 | 450 | - (void)runTestsInClass: (Class)testClass 451 | { 452 | _testClassesRun++; 453 | 454 | NSArray *testMethods = nil; 455 | 456 | /* Test class methods */ 457 | 458 | if (testClass != nil) 459 | { 460 | testMethods = [self filterTestMethodNames: UKTestMethodNamesFromClass(objc_getMetaClass(class_getName(testClass)))]; 461 | } 462 | [self runTests: testMethods onInstance: NO ofClass: testClass]; 463 | 464 | /* Test instance methods */ 465 | 466 | testMethods = [self filterTestMethodNames: UKTestMethodNamesFromClass(testClass)]; 467 | [self runTests: testMethods onInstance: YES ofClass: testClass]; 468 | } 469 | 470 | - (NSArray *)filterTestClassNames: (NSArray *)testClassNames 471 | { 472 | if (nil != _className) 473 | { 474 | if ([testClassNames containsObject: _className]) 475 | { 476 | return @[_className]; 477 | } 478 | return [NSArray array]; 479 | } 480 | 481 | NSMutableArray *filteredClassNames = [NSMutableArray array]; 482 | 483 | for (NSString *testClassName in testClassNames) 484 | { 485 | if (_classRegex == nil || [testClassName rangeOfString: _classRegex 486 | options: NSRegularExpressionSearch].location != NSNotFound) 487 | { 488 | [filteredClassNames addObject: testClassName]; 489 | } 490 | } 491 | 492 | return filteredClassNames; 493 | } 494 | 495 | - (NSArray *)filterTestMethodNames: (NSArray *)testMethodNames 496 | { 497 | if (nil != _methodName) 498 | { 499 | if ([testMethodNames containsObject: _methodName]) 500 | { 501 | return @[_methodName]; 502 | } 503 | return [NSArray array]; 504 | } 505 | 506 | NSMutableArray *filteredMethodNames = [NSMutableArray array]; 507 | 508 | for (NSString *testMethodName in testMethodNames) 509 | { 510 | if (_methodRegex == nil || [testMethodName rangeOfString: self.methodRegex 511 | options: NSRegularExpressionSearch].location != NSNotFound) 512 | { 513 | [filteredMethodNames addObject: testMethodName]; 514 | } 515 | } 516 | 517 | return filteredMethodNames; 518 | } 519 | 520 | - (void)runTestsInBundle: (NSBundle *)bundle 521 | { 522 | NILARG_EXCEPTION_TEST(bundle); 523 | 524 | [self runTestsWithClassNames: nil 525 | inBundle: bundle 526 | principalClass: bundle.principalClass]; 527 | } 528 | 529 | - (void)runTestsWithClassNames: (NSArray *)testClassNames 530 | principalClass: (Class)principalClass 531 | { 532 | [self runTestsWithClassNames: testClassNames 533 | inBundle: [NSBundle mainBundle] 534 | principalClass: principalClass]; 535 | } 536 | 537 | /** 538 | * We must call UKTestClassNamesFromBundle() after +willRunTestSuite, otherwise 539 | * the wrong app object can be created in a UI related test suite on Mac OS X... 540 | * 541 | * On Mac OS X, we have -bundleForClass: that invokes class_respondsToSelector() 542 | * which results in +initialize being called, and +[NSWindowBinder initialize] 543 | * has the bad idea to use +sharedApplication. 544 | * When no app object is available yet, an NSApplication instance will be 545 | * created rather than the subclass instance we might want. 546 | * 547 | * This is why we don't call UKTestClassNamesFromBundle() in 548 | * -runTestsInBundle:principalClass:. 549 | */ 550 | - (void)runTestsWithClassNames: (NSArray *)testClassNames 551 | inBundle: (NSBundle *)bundle 552 | principalClass: (Class)principalClass 553 | { 554 | NSDate *startDate = [NSDate date]; 555 | 556 | if ([principalClass respondsToSelector: @selector(willRunTestSuite)]) 557 | { 558 | [principalClass willRunTestSuite]; 559 | } 560 | 561 | NSArray *classNames = 562 | (testClassNames != nil ? testClassNames : UKTestClassNamesFromBundle(bundle)); 563 | 564 | for (NSString *name in [self filterTestClassNames: classNames]) 565 | { 566 | [self runTestsInClass: NSClassFromString(name)]; 567 | } 568 | 569 | if ([principalClass respondsToSelector: @selector(didRunTestSuite)]) 570 | { 571 | [principalClass didRunTestSuite]; 572 | } 573 | 574 | NSLog(@"Took %d ms\n", (int)([[NSDate date] timeIntervalSinceDate: startDate] * 1000)); 575 | } 576 | 577 | #pragma mark - Reporting Test Results 578 | 579 | - (int)reportTestResults 580 | { 581 | int testsPassed = [UKTestHandler handler].testsPassed; 582 | int testsFailed = [UKTestHandler handler].testsFailed; 583 | int exceptionsReported = [UKTestHandler handler].exceptionsReported; 584 | 585 | // TODO: May be be extract in -testResultSummary 586 | NSLog(@"Result: %i classes, %i methods, %i tests, %i failed, %i exceptions", 587 | _testClassesRun, _testMethodsRun, (testsPassed + testsFailed), testsFailed, exceptionsReported); 588 | 589 | return (testsFailed == 0 && exceptionsReported == 0 ? 0 : -1); 590 | } 591 | 592 | @end 593 | 594 | BOOL UKTestClassConformsToProtocol(Class aClass) 595 | { 596 | Class class = aClass; 597 | BOOL isTestClass = NO; 598 | 599 | while (class != Nil && !isTestClass) 600 | { 601 | isTestClass = class_conformsToProtocol(class, @protocol(UKTest)); 602 | class = class_getSuperclass(class); 603 | } 604 | return isTestClass; 605 | } 606 | 607 | NSArray *UKTestClassNamesFromBundle(NSBundle *bundle) 608 | { 609 | NSMutableArray *testClasseNames = [NSMutableArray array]; 610 | int numClasses = objc_getClassList(NULL, 0); 611 | 612 | if (numClasses > 0) 613 | { 614 | Class *classes = (Class *)malloc(sizeof(Class) * numClasses); 615 | 616 | objc_getClassList(classes, numClasses); 617 | 618 | for (int i = 0; i < numClasses; i++) 619 | { 620 | Class c = classes[i]; 621 | 622 | /* Using class_conformsToProtocol() intead of +conformsToProtocol: 623 | does not require sending a message to the class. This prevents 624 | +initialize being sent to classes that are not explicitly used. 625 | 626 | Note: +bundleForClass: will initialize test classes on Mac OS X. */ 627 | if (UKTestClassConformsToProtocol(c) && bundle == [NSBundle bundleForClass: c]) 628 | { 629 | [testClasseNames addObject: NSStringFromClass(c)]; 630 | } 631 | } 632 | free(classes); 633 | } 634 | 635 | return [testClasseNames sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)]; 636 | } 637 | 638 | 639 | NSArray *UKTestMethodNamesFromClass(Class sourceClass) 640 | { 641 | NSMutableArray *testMethods = [NSMutableArray array]; 642 | 643 | for (Class c = sourceClass; c != Nil; c = class_getSuperclass(c)) 644 | { 645 | unsigned int methodCount = 0; 646 | Method *methodList = class_copyMethodList(c, &methodCount); 647 | Method method = NULL; 648 | 649 | for (int i = 0; i < methodCount; i++) 650 | { 651 | method = methodList[i]; 652 | SEL sel = method_getName(method); 653 | NSString *methodName = NSStringFromSelector(sel); 654 | 655 | if ([methodName hasPrefix: @"test"]) 656 | { 657 | [testMethods addObject: methodName]; 658 | } 659 | } 660 | free(methodList); 661 | } 662 | 663 | return [testMethods sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)]; 664 | } 665 | -------------------------------------------------------------------------------- /FrameworkSource/UKTest.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) 2004 James Duncan Davidson, Michael Milvich, Nicolas Roard 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | 24 | /** 25 | * @abstract The protocol that marks a class as a test class. 26 | * 27 | * All classes that conforms to UKTest, including their subclasses, are picked 28 | * up by UKRunner. 29 | * 30 | * If a filtering option such as -c is passed to ukrun, this 31 | * can prevent the a test class to be picked up. 32 | */ 33 | @protocol UKTest 34 | @end 35 | 36 | /** 37 | * Reports a success. 38 | */ 39 | #define UKPass() [[UKTestHandler handler] passInFile:__FILE__ line:__LINE__] 40 | /** 41 | * Reports a failure. 42 | */ 43 | #define UKFail() [[UKTestHandler handler] failInFile:__FILE__ line:__LINE__] 44 | /** 45 | * Tests that an expression is true. 46 | */ 47 | #define UKTrue(condition) [[UKTestHandler handler] testTrue:(condition) inFile:__FILE__ line:__LINE__] 48 | /** 49 | * Tests that an expression is false. 50 | */ 51 | #define UKFalse(condition) [[UKTestHandler handler] testFalse:(condition) inFile:__FILE__ line:__LINE__] 52 | /** 53 | * Tests that ref == nil. 54 | */ 55 | #define UKNil(ref) [[UKTestHandler handler] testNil:(ref) inFile:__FILE__ line:__LINE__] 56 | /** 57 | * Tests that ref != nil. 58 | */ 59 | #define UKNotNil(ref) [[UKTestHandler handler] testNotNil:(ref) inFile:__FILE__ line:__LINE__] 60 | /** 61 | * Tests that two primitive integers are equal. 62 | * 63 | * a is the expected value and b the tested value. 64 | * 65 | * Don't pass unsigned long long integers that cannot safely casted to long long. 66 | */ 67 | #define UKIntsEqual(a, b) [[UKTestHandler handler] testInt:((long long)a) equalTo:((long long)b) inFile:__FILE__ line:__LINE__] 68 | /** 69 | * Tests that two primitive integers are not equal. 70 | * 71 | * a is the non-expected value and b the tested value. 72 | * 73 | * Don't pass unsigned long long integers that cannot safely casted to long long. 74 | */ 75 | #define UKIntsNotEqual(a, b) [[UKTestHandler handler] testInt:((long long)a) notEqualTo:((long long)b) inFile:__FILE__ line:__LINE__] 76 | /** 77 | * Tests that two primitive floats are equal or almost, this evaluates whether 78 | * fabs(a - b) <= d is true. 79 | * 80 | * d is the error margin. 81 | * 82 | * a is the expected value and b the tested value. 83 | */ 84 | #define UKFloatsEqual(a, b, d) [[UKTestHandler handler] testFloat:(a) equalTo:(b) delta:(d) inFile:__FILE__ line:__LINE__] 85 | /** 86 | * Tests that two primitive floats are not equal, this evaluates whether 87 | * fabs(a - b) > d is true. 88 | * 89 | * d is the error margin. 90 | * 91 | * a is the non-expected value and b the tested value. 92 | */ 93 | #define UKFloatsNotEqual(a, b, d) [[UKTestHandler handler] testFloat:(a) notEqualTo:(b) delta:(d) inFile:__FILE__ line:__LINE__] 94 | /** 95 | * Tests macro that a is a subclass of b, this uses -[NSObject isKindOfClass:] 96 | * behind the scene. 97 | * 98 | * Most of the time UKObjectsEqual([a class], [b class]) would be 99 | * similar, but not always (i.e. NSCFArray/NSArray on Mac OS X). Example: 100 | * 101 | * 102 | * UKObjectKindOf(myObject, NSArray) 103 | * 104 | */ 105 | #define UKObjectKindOf(a, b) [[UKTestHandler handler] testObject:(a) kindOf:[b class] inFile:__FILE__ line:__LINE__] 106 | /** 107 | * Tests that [a isEqual: b]. 108 | * 109 | * a is the expected value and b the tested value. 110 | */ 111 | #define UKObjectsEqual(a, b) [[UKTestHandler handler] testObject:(a) equalTo:(b) inFile:__FILE__ line:__LINE__] 112 | /** 113 | * Tests that ![a isEqual: b]. 114 | * 115 | * a is the non-expected value and b the tested value. 116 | */ 117 | #define UKObjectsNotEqual(a, b) [[UKTestHandler handler] testObject:(a) notEqualTo:(b) inFile:__FILE__ line:__LINE__] 118 | /** 119 | * Tests that the objects are identical with a == b. 120 | * 121 | * a is the expected value and b the tested value. 122 | */ 123 | #define UKObjectsSame(a, b) [[UKTestHandler handler] testObject:(a) sameAs:(b) inFile:__FILE__ line:__LINE__] 124 | /** 125 | * Tests that the objects are not identical with a != b. 126 | * 127 | * a is the non-expected value and b the tested value. 128 | */ 129 | #define UKObjectsNotSame(a, b) [[UKTestHandler handler] testObject:(a) notSameAs:(b) inFile:__FILE__ line:__LINE__] 130 | /** 131 | * Tests that [a isEqual: b]. 132 | * 133 | * a is the expected value and b the tested value. 134 | * 135 | * This is the same than UKObjectsEqual(), this just helps readibility a bit, 136 | * since testing string equality is pretty common. 137 | */ 138 | #define UKStringsEqual(a, b) [[UKTestHandler handler] testString:(a) equalTo:(b) inFile:__FILE__ line:__LINE__] 139 | /** 140 | * Tests that ![a isEqual: b]. 141 | * 142 | * a is the non-expected value and b the tested value. 143 | * 144 | * This is the same than UKObjectsNotEqual(), this just helps readibility a bit, 145 | * since testing string equality is pretty common. 146 | */ 147 | #define UKStringsNotEqual(a, b) [[UKTestHandler handler] testString:(a) notEqualTo:(b) inFile:__FILE__ line:__LINE__] 148 | /** 149 | * Tests that b is a substring of a, this uses -[NSString rangeOfString:]. 150 | */ 151 | #define UKStringContains(a, b) [[UKTestHandler handler] testString:(a) contains:(b) inFile:__FILE__ line:__LINE__] 152 | /** 153 | * Tests that b is not a substring of a, this uses -[NSString rangeOfString:]. 154 | */ 155 | #define UKStringDoesNotContain(a, b) [[UKTestHandler handler] testString:(a) doesNotContain:(b) inFile:__FILE__ line:__LINE__] 156 | /** Tests that the code piece raises an exception. 157 | 158 | The exception testing macros get a bit more involved than all the other ones 159 | we have here because of the need for embedding the try-catch in the generated 160 | code. In addition, the statements are wrapped in a do{...}while(NO) block so 161 | that the generated code is sane even if the macro appears in a context like: 162 | 163 | 164 | if (someFlag) 165 | UKRaisesException(someExpression) 166 | else 167 | UKRaisesException(someOtherExpression) 168 | */ 169 | #define UKRaisesException(a) do{id p_exp = nil; @try { a; } @catch(id exp) { p_exp = exp; } [[UKTestHandler handler] raisesException:p_exp inFile:__FILE__ line:__LINE__]; } while(NO) 170 | /** Tests that the code piece raises no exception. 171 | 172 | See also UKRaisesException(). */ 173 | #define UKDoesNotRaiseException(a) do{id p_exp = nil; @try { a; } @catch(id exp) { p_exp = exp; } [[UKTestHandler handler] doesNotRaisesException:p_exp inFile:__FILE__ line:__LINE__]; } while(NO) 174 | /** Tests that the code piece raises an exception of the name b. 175 | 176 | See also -[NSException name]. */ 177 | #define UKRaisesExceptionNamed(a, b) do{ id p_exp = nil; @try{ a; } @catch(id exp) { p_exp = exp;}[[UKTestHandler handler] raisesException:p_exp named:b inFile:__FILE__ line:__LINE__]; } while(NO) 178 | /** Tests that the code piece raises an exception of the class name b. 179 | 180 | See NSException. */ 181 | #define UKRaisesExceptionClass(a, b) do{ id p_exp = nil; @try{ a; } @catch(id exp) { p_exp = exp;}[[UKTestHandler handler] raisesException:p_exp class:[b class] inFile:__FILE__ line:__LINE__]; } while(NO) 182 | -------------------------------------------------------------------------------- /FrameworkSource/UKTestHandler.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) 2004 James Duncan Davidson, Michael Milvich, Mark Dalrymple, Nicolas Roard, Quentin Mathe 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | 24 | /** 25 | * @abstract UKTestHandler implements the test assertions built into UnitKit 26 | * and track the test results 27 | * 28 | * For each test assertion invoked on the test handler, the handler collects 29 | * the result and reports it or not based on the reporting settings. 30 | * 31 | * At any time, you can query the current test results using -testsPassed, 32 | * -testsFailed and -exceptionsReported, for all the test assertions invoked 33 | * since the test handler has been created. 34 | * 35 | * A single test handler exists for all UKRunner instances. For multiple run 36 | * test requests against UKRunner instances, all test results are reported 37 | * together. 38 | */ 39 | @interface UKTestHandler : NSObject 40 | 41 | 42 | /** @taskunit Initialization */ 43 | 44 | 45 | /** 46 | * Returns the shared test handler. 47 | */ 48 | + (UKTestHandler *)handler; 49 | 50 | 51 | /** @taskunit Controlling Test Result Reporting */ 52 | 53 | 54 | /** 55 | * Returns a delegate that can implement the same reporting methods than 56 | * UKTestHandler. 57 | * 58 | * By default, returns nil. 59 | * 60 | * For more details, see -setDelegate:. 61 | */ 62 | @property (nonatomic, weak) id delegate; 63 | /** 64 | * Sets a delegate that can implement the same reporting methods than 65 | * UKTestHandler. 66 | * 67 | * If the delegate implements a reporting method, it takes priority over 68 | * UKTestHandler. 69 | * As a result, what was previously reported by UKTestHandler is not going to 70 | * be automatically logged in the console unless the delegate does it. 71 | */ 72 | /** 73 | * Returns whether the handler should report just the test failures and 74 | * uncaught exceptions, but nothing on test successes. 75 | * 76 | * By default, returns NO. 77 | * 78 | * -isQuiet is initialized to YES if the argument -q is present in the 79 | * ukrun arguments. 80 | */ 81 | @property (nonatomic, getter=isQuiet) BOOL quiet; 82 | /** 83 | * Tells the handler to report just the test failures and uncaught exceptions, 84 | * but nothing on test successes. 85 | */ 86 | /** 87 | * If we have a delegate, then by all means use it. If we don't, then check to 88 | * see if we have any errors which should be reported off to std out. 89 | */ 90 | - (void)reportStatus: (BOOL)cond 91 | inFile: (const char *)filename 92 | line: (int)line 93 | message: (NSString *)msg; 94 | /** 95 | * Reports an uncaught exception and a hint that represents the context in 96 | * which the exception was raised. 97 | * 98 | * To indicate the context, three hints are supported: 99 | * 100 | * 101 | * errExceptionOnInitinside -init on a test object 102 | * errExceptionOnReleaseinside -dealloc on a test object 103 | * a test method nameinside a test method 104 | * 105 | * 106 | * By default, forwards the message to the delegate if there is one, otherwise 107 | * uses -reportWarning: to print the exception reason. 108 | */ 109 | - (void)reportException: (NSException *)exception 110 | inClass: (Class)testClass 111 | hint: (NSString *)hint; 112 | /** 113 | * Reports a warning message. 114 | * 115 | * By default, forwards the message to the delegate if there is one, otherwise 116 | * uses NSLog() to print the message. 117 | * 118 | * This method is used by -reportStatus:inFile:line:message: and 119 | * -reportException:inClass:hint: to report test failures and uncaught exceptions. 120 | */ 121 | - (void)reportWarning: (NSString *)message; 122 | 123 | 124 | /** @taskunit Test Results */ 125 | 126 | 127 | /** 128 | * Returns the current number of test successes. 129 | * 130 | * See -reportStatus:inFile:line:message:. 131 | */ 132 | @property (nonatomic, readonly) int testsPassed; 133 | /** 134 | * Returns the current number of test failures. 135 | * 136 | * See -reportStatus:inFile:line:message:. 137 | */ 138 | @property (nonatomic, readonly) int testsFailed; 139 | /** 140 | * Returns the current number of exceptions caught by UKRunner and reported to 141 | * the test handler. 142 | * 143 | * See -reportException:inClass:hint:. 144 | */ 145 | @property (nonatomic, readonly) int exceptionsReported; 146 | 147 | 148 | /** @taskunit Basic Test Assertions */ 149 | 150 | 151 | - (void)passInFile: (const char *)filename 152 | line: (int)line; 153 | - (void)failInFile: (const char *)filename 154 | line: (int)line; 155 | 156 | 157 | /** @taskunit Primitive Test Assertions */ 158 | 159 | 160 | - (void)testTrue: (BOOL)cond 161 | inFile: (const char *)filename 162 | line: (int)line; 163 | - (void)testFalse: (BOOL)cond 164 | inFile: (const char *)filename 165 | line: (int)line; 166 | - (void)testNil: (id)ref 167 | inFile: (const char *)filename 168 | line: (int)line; 169 | - (void)testNotNil: (id)ref 170 | inFile: (const char *)filename 171 | line: (int)line; 172 | 173 | 174 | /** @taskunit Number Primitive Test Assertions */ 175 | 176 | 177 | - (void)testInt: (long long)a 178 | equalTo: (long long)b 179 | inFile: (const char *)filename 180 | line: (int)line; 181 | - (void)testInt: (long long)a 182 | notEqualTo: (long long)b 183 | inFile: (const char *)filename 184 | line: (int)line; 185 | - (void)testFloat: (float)a 186 | equalTo: (float)b 187 | delta: (float)delta 188 | inFile: (const char *)filename 189 | line: (int)line; 190 | - (void)testFloat: (float)a 191 | notEqualTo: (float)b 192 | delta: (float)delta 193 | inFile: (const char *)filename 194 | line: (int)line; 195 | 196 | 197 | /** @taskunit Object Test Assertions */ 198 | 199 | 200 | - (void)testObject: (id)a 201 | kindOf: (id)b 202 | inFile: (const char *)filename 203 | line: (int)line; 204 | - (void)testObject: (id)a 205 | equalTo: (id)b 206 | inFile: (const char *)filename 207 | line: (int)line; 208 | - (void)testObject: (id)a 209 | notEqualTo: (id)b 210 | inFile: (const char *)filename 211 | line: (int)line; 212 | - (void)testObject: (id)a 213 | sameAs: (id)b 214 | inFile: (const char *)filename 215 | line: (int)line; 216 | - (void)testObject: (id)a 217 | notSameAs: (id)b 218 | inFile: (const char *)filename 219 | line: (int)line; 220 | 221 | 222 | /** @taskunit String Test Assertions */ 223 | 224 | 225 | - (void)testString: (NSString *)a 226 | equalTo: (NSString *)b 227 | inFile: (const char *)filename 228 | line: (int)line; 229 | - (void)testString: (NSString *)a 230 | notEqualTo: (NSString *)b 231 | inFile: (const char *)filename 232 | line: (int)line; 233 | - (void)testString: (NSString *)a 234 | contains: (NSString *)b 235 | inFile: (const char *)filename 236 | line: (int)line; 237 | - (void)testString: (NSString *)a 238 | doesNotContain: (NSString *)b 239 | inFile: (const char *)filename 240 | line: (int)line; 241 | 242 | 243 | /** @taskunit Exception Test Assertions */ 244 | 245 | 246 | - (void)raisesException: (NSException *)exception 247 | inFile: (const char *)filename 248 | line: (int)line; 249 | - (void)doesNotRaisesException: (NSException *)exception 250 | inFile: (const char *)filename 251 | line: (int)line; 252 | - (void)raisesException: (NSException *)exception 253 | named: (NSString *)expected 254 | inFile: (const char *)filename 255 | line: (int)line; 256 | - (void)raisesException: (id)raisedObject 257 | class: (Class)expectedClass 258 | inFile: (const char *)filename 259 | line: (int)line; 260 | 261 | @end 262 | -------------------------------------------------------------------------------- /FrameworkSource/UKTestHandler.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson, Michael Milvich, Mark Dalrymple, Nicolas Roard, Quentin Mathe 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "UKTestHandler.h" 23 | 24 | @implementation UKTestHandler 25 | 26 | #pragma mark - Initialization 27 | 28 | + (UKTestHandler *)handler 29 | { 30 | static UKTestHandler *handler = nil; 31 | 32 | if (handler == nil) 33 | { 34 | handler = [[self alloc] init]; 35 | } 36 | return handler; 37 | } 38 | 39 | #pragma mark - Localization Support 40 | 41 | + (NSString *)localizedString: (NSString *)key 42 | { 43 | NSBundle *bundle = [NSBundle bundleForClass: [self class]]; 44 | return NSLocalizedStringFromTableInBundle(key, @"UKTestHandler", bundle, @""); 45 | } 46 | 47 | + (NSString *)displayStringForObject: (id)obj 48 | { 49 | NSString *description = [obj description]; 50 | // TODO: It might be nice to abbreviate the descriptions if the test passes and 51 | // print the whole description if the test fails. For now, always print the 52 | // whole description since it's very annoying to see failed tests with an 53 | // useless truncated description 54 | #if 0 55 | if ([description hasPrefix:@"<"] && [description hasSuffix:@">"]) 56 | { 57 | // assume it's and return 58 | if ([description length] < 30) 59 | { 60 | return description; 61 | } 62 | else 63 | { 64 | description = [description substringWithRange:NSMakeRange(0, 26)]; 65 | description = [description stringByAppendingString:@"...>"]; 66 | return description; 67 | } 68 | } 69 | else if ([description length] > 30) 70 | { 71 | description = [description substringWithRange:NSMakeRange(0, 27)]; 72 | description = [description stringByAppendingString:@"..."]; 73 | } 74 | #endif 75 | return [NSString stringWithFormat: @"\"%@\"", description]; 76 | } 77 | 78 | + (NSString *)displayStringForException: (id)exc 79 | { 80 | if ([exc isKindOfClass: [NSException class]]) 81 | { 82 | return [NSString stringWithFormat: @"NSException: %@ %@", 83 | [exc name], [exc reason]]; 84 | } 85 | else 86 | { 87 | return NSStringFromClass([exc class]); 88 | } 89 | } 90 | 91 | #pragma mark - Controlling Test Result Reporting 92 | 93 | - (void)reportStatus: (BOOL)cond 94 | inFile: (const char *)filename 95 | line: (int)line 96 | message: (NSString *)msg 97 | { 98 | if (_delegate != nil 99 | && [_delegate respondsToSelector: @selector(reportStatus:inFile:line:message:)]) 100 | { 101 | [_delegate reportStatus: cond inFile: filename line: line message: msg]; 102 | return; 103 | } 104 | else if (cond) 105 | { 106 | _testsPassed++; 107 | 108 | if (!_quiet) 109 | { 110 | NSLog(@"%s:%i %s\n", filename, line, msg.UTF8String); 111 | } 112 | } 113 | else 114 | { 115 | _testsFailed++; 116 | 117 | NSLog(@"%s:%i: warning: %s\n", filename, line, msg.UTF8String); 118 | } 119 | } 120 | 121 | - (void)reportException: (NSException *)exception 122 | inClass: (Class)testClass 123 | hint: (NSString *)hint 124 | { 125 | if (_delegate != nil 126 | && [_delegate respondsToSelector: @selector(reportException:inClass:hint:)]) 127 | { 128 | [_delegate reportException: exception inClass: testClass hint: hint]; 129 | } 130 | else 131 | { 132 | _exceptionsReported++; 133 | 134 | NSString *excstring = [[self class] displayStringForException: exception]; 135 | NSString *msg = nil; 136 | 137 | if ([hint isEqual: @"errExceptionOnInit"] || [hint isEqual: @"errExceptionOnRelease"]) 138 | { 139 | msg = [[self class] localizedString: hint]; 140 | msg = [NSString stringWithFormat: msg, 141 | NSStringFromClass(testClass), 142 | excstring, 143 | exception.callStackSymbols]; 144 | } 145 | else 146 | { 147 | NSString *testMethodName = hint; 148 | 149 | msg = [[self class] localizedString: @"errExceptionInTestMethod"]; 150 | msg = [NSString stringWithFormat: msg, 151 | NSStringFromClass(testClass), 152 | testMethodName, 153 | excstring, 154 | exception.callStackSymbols]; 155 | } 156 | 157 | [self reportWarning: msg]; 158 | } 159 | } 160 | 161 | - (void)reportWarning: (NSString *)msg 162 | { 163 | if (_delegate != nil && [_delegate respondsToSelector: @selector(reportWarning:)]) 164 | { 165 | [_delegate reportWarning: msg]; 166 | } 167 | else 168 | { 169 | NSLog(@":: warning: %s\n", msg.UTF8String); 170 | } 171 | } 172 | 173 | #pragma mark - Basic Test Assertions 174 | 175 | - (void)passInFile: (const char *)filename 176 | line: (int)line 177 | { 178 | NSString *msg = [UKTestHandler localizedString: @"msgUKPass"]; 179 | 180 | [self reportStatus: YES inFile: filename line: line message: msg]; 181 | } 182 | 183 | - (void)failInFile: (const char *)filename 184 | line: (int)line 185 | { 186 | NSString *msg = [UKTestHandler localizedString: @"msgUKFail"]; 187 | 188 | [self reportStatus: NO inFile: filename line: line message: msg]; 189 | } 190 | 191 | #pragma mark - Primitive Test Assertions 192 | 193 | - (void)testTrue: (BOOL)cond 194 | inFile: (const char *)filename 195 | line: (int)line 196 | { 197 | if (cond) 198 | { 199 | NSString *msg = [UKTestHandler localizedString: @"msgUKTrue.pass"]; 200 | 201 | [self reportStatus: YES inFile: filename line: line message: msg]; 202 | } 203 | else 204 | { 205 | NSString *msg = [UKTestHandler localizedString: @"msgUKTrue.fail"]; 206 | 207 | [self reportStatus: NO inFile: filename line: line message: msg]; 208 | } 209 | } 210 | 211 | - (void)testFalse: (BOOL)cond 212 | inFile: (const char *)filename 213 | line: (int)line 214 | { 215 | if (!cond) 216 | { 217 | NSString *msg = [UKTestHandler localizedString: @"msgUKFalse.pass"]; 218 | 219 | [self reportStatus: YES inFile: filename line: line message: msg]; 220 | } 221 | else 222 | { 223 | NSString *msg = [UKTestHandler localizedString: @"msgUKFalse.fail"]; 224 | 225 | [self reportStatus: NO inFile: filename line: line message: msg]; 226 | } 227 | } 228 | 229 | - (void)testNil: (id)ref 230 | inFile: (const char *)filename 231 | line: (int)line 232 | { 233 | if (ref == nil) 234 | { 235 | NSString *msg = [UKTestHandler localizedString: @"msgUKNil.pass"]; 236 | 237 | [self reportStatus: YES inFile: filename line: line message: msg]; 238 | } 239 | else 240 | { 241 | NSString *msg = [UKTestHandler localizedString: @"msgUKNil.fail"]; 242 | NSString *s = [UKTestHandler displayStringForObject: ref]; 243 | msg = [NSString stringWithFormat: msg, s]; 244 | 245 | [self reportStatus: NO inFile: filename line: line message: msg]; 246 | } 247 | } 248 | 249 | - (void)testNotNil: (id)ref 250 | inFile: (const char *)filename 251 | line: (int)line 252 | { 253 | if (ref != nil) 254 | { 255 | NSString *msg = [UKTestHandler localizedString: @"msgUKNotNil.pass"]; 256 | NSString *s = [UKTestHandler displayStringForObject: ref]; 257 | msg = [NSString stringWithFormat: msg, s]; 258 | 259 | [self reportStatus: YES inFile: filename line: line message: msg]; 260 | } 261 | else 262 | { 263 | NSString *msg = [UKTestHandler localizedString: @"msgUKNotNil.fail"]; 264 | 265 | [self reportStatus: NO inFile: filename line: line message: msg]; 266 | } 267 | } 268 | 269 | #pragma mark - Primitive Number Test Assertions 270 | 271 | - (void)testInt: (long long)a 272 | equalTo: (long long)b 273 | inFile: (const char *)filename 274 | line: (int)line 275 | { 276 | if (a == b) 277 | { 278 | NSString *msg = [UKTestHandler localizedString: @"msgUKIntsEqual.pass"]; 279 | msg = [NSString stringWithFormat: msg, a, b]; 280 | 281 | [self reportStatus: YES inFile: filename line: line message: msg]; 282 | } 283 | else 284 | { 285 | NSString *msg = [UKTestHandler localizedString: @"msgUKIntsEqual.fail"]; 286 | msg = [NSString stringWithFormat: msg, a, b]; 287 | 288 | [self reportStatus: NO inFile: filename line: line message: msg]; 289 | } 290 | } 291 | 292 | - (void)testInt: (long long)a 293 | notEqualTo: (long long)b 294 | inFile: (const char *)filename 295 | line: (int)line 296 | { 297 | if (a != b) 298 | { 299 | NSString *msg = [UKTestHandler localizedString: @"msgUKIntsNotEqual.pass"]; 300 | msg = [NSString stringWithFormat: msg, a, b]; 301 | 302 | [self reportStatus: YES inFile: filename line: line message: msg]; 303 | } 304 | else 305 | { 306 | NSString *msg = [UKTestHandler localizedString: @"msgUKIntsNotEqual.fail"]; 307 | msg = [NSString stringWithFormat: msg, a, b]; 308 | 309 | [self reportStatus: NO inFile: filename line: line message: msg]; 310 | } 311 | } 312 | 313 | - (void)testFloat: (float)a 314 | equalTo: (float)b 315 | delta: (float)delta 316 | inFile: (const char *)filename 317 | line: (int)line 318 | { 319 | // TODO: Need to figure out how to report the numbers in such a way that 320 | // they are shortened to the degree of precision... 321 | float c = fabs(a - b); 322 | 323 | if (c <= delta) 324 | { 325 | NSString *msg = [UKTestHandler localizedString: @"msgUKFloatsEqual.pass"]; 326 | msg = [NSString stringWithFormat: msg, a - delta, a + delta, b]; 327 | 328 | [self reportStatus: YES inFile: filename line: line message: msg]; 329 | } 330 | else 331 | { 332 | NSString *msg = [UKTestHandler localizedString: @"msgUKFloatsEqual.fail"]; 333 | msg = [NSString stringWithFormat: msg, a - delta, a + delta, b]; 334 | 335 | [self reportStatus: NO inFile: filename line: line message: msg]; 336 | } 337 | } 338 | 339 | - (void)testFloat: (float)a 340 | notEqualTo: (float)b 341 | delta: (float)delta 342 | inFile: (const char *)filename 343 | line: (int)line 344 | { 345 | // TODO: Need to figure out how to report the numbers in such a way that 346 | // they are shortened to the degree of precision... 347 | float c = fabs(a - b); 348 | 349 | if (c > delta) 350 | { 351 | NSString *msg = [UKTestHandler localizedString: @"msgUKFloatsNotEqual.pass"]; 352 | msg = [NSString stringWithFormat: msg, a - delta, a + delta, b]; 353 | 354 | [self reportStatus: YES inFile: filename line: line message: msg]; 355 | } 356 | else 357 | { 358 | NSString *msg = [UKTestHandler localizedString: @"msgUKFloatsNotEqual.fail"]; 359 | msg = [NSString stringWithFormat: msg, a - delta, a + delta, b]; 360 | 361 | [self reportStatus: NO inFile: filename line: line message: msg]; 362 | } 363 | } 364 | 365 | #pragma mark - Object Test Assertions 366 | 367 | - (void)testObject: (id)a 368 | kindOf: (id)b 369 | inFile: (const char *)filename 370 | line: (int)line 371 | { 372 | NSString *dispA = [UKTestHandler displayStringForObject: [a class]]; 373 | NSString *dispB = [UKTestHandler displayStringForObject: b]; 374 | 375 | if ([a isKindOfClass: b]) 376 | { 377 | NSString *msg = [UKTestHandler localizedString: @"msgUKObjectKindOf.pass"]; 378 | msg = [NSString stringWithFormat: msg, dispB, dispA]; 379 | 380 | [self reportStatus: YES inFile: filename line: line message: msg]; 381 | } 382 | else 383 | { 384 | NSString *msg = [UKTestHandler localizedString: @"msgUKObjectKindOf.fail"]; 385 | msg = [NSString stringWithFormat: msg, dispB, dispA]; 386 | 387 | [self reportStatus: NO inFile: filename line: line message: msg]; 388 | } 389 | } 390 | 391 | - (void)testObject: (id)a equalTo: (id)b inFile: (const char *)filename line: (int)line 392 | { 393 | NSString *dispA = [UKTestHandler displayStringForObject: a]; 394 | NSString *dispB = [UKTestHandler displayStringForObject: b]; 395 | 396 | if ([a isEqual: b]) 397 | { 398 | NSString *msg = [UKTestHandler localizedString: @"msgUKObjectsEqual.pass"]; 399 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 400 | 401 | [self reportStatus: YES inFile: filename line: line message: msg]; 402 | } 403 | else 404 | { 405 | NSString *msg = [UKTestHandler localizedString: @"msgUKObjectsEqual.fail"]; 406 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 407 | 408 | [self reportStatus: NO inFile: filename line: line message: msg]; 409 | } 410 | } 411 | 412 | - (void)testObject: (id)a 413 | notEqualTo: (id)b 414 | inFile: (const char *)filename 415 | line: (int)line 416 | { 417 | NSString *dispA = [UKTestHandler displayStringForObject: a]; 418 | NSString *dispB = [UKTestHandler displayStringForObject: b]; 419 | 420 | if (![a isEqual: b]) 421 | { 422 | NSString *msg = [UKTestHandler localizedString: @"msgUKObjectsNotEqual.pass"]; 423 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 424 | 425 | [self reportStatus: YES inFile: filename line: line message: msg]; 426 | } 427 | else 428 | { 429 | NSString *msg = [UKTestHandler localizedString: @"msgUKObjectsNotEqual.fail"]; 430 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 431 | 432 | [self reportStatus: NO inFile: filename line: line message: msg]; 433 | } 434 | } 435 | 436 | - (void)testObject: (id)a 437 | sameAs: (id)b 438 | inFile: (const char *)filename 439 | line: (int)line 440 | { 441 | NSString *dispA = [UKTestHandler displayStringForObject: a]; 442 | NSString *dispB = [UKTestHandler displayStringForObject: b]; 443 | 444 | if (a == b) 445 | { 446 | NSString *msg = [UKTestHandler localizedString: @"msgUKObjectsSame.pass"]; 447 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 448 | 449 | [self reportStatus: YES inFile: filename line: line message: msg]; 450 | } 451 | else 452 | { 453 | NSString *msg = [UKTestHandler localizedString: @"msgUKObjectsSame.fail"]; 454 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 455 | 456 | [self reportStatus: NO inFile: filename line: line message: msg]; 457 | } 458 | } 459 | 460 | - (void)testObject: (id)a 461 | notSameAs: (id)b 462 | inFile: (const char *)filename 463 | line: (int)line 464 | { 465 | NSString *dispA = [UKTestHandler displayStringForObject: a]; 466 | NSString *dispB = [UKTestHandler displayStringForObject: b]; 467 | 468 | if (a != b) 469 | { 470 | NSString *msg = [UKTestHandler localizedString: @"msgUKObjectsNotSame.pass"]; 471 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 472 | 473 | [self reportStatus: YES inFile: filename line: line message: msg]; 474 | } 475 | else 476 | { 477 | NSString *msg = [UKTestHandler localizedString: @"msgUKObjectsNotSame.fail"]; 478 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 479 | 480 | [self reportStatus: NO inFile: filename line: line message: msg]; 481 | } 482 | } 483 | 484 | #pragma mark - String Test Assertions 485 | 486 | - (void)testString: (NSString *)a 487 | equalTo: (NSString *)b 488 | inFile: (const char *)filename 489 | line: (int)line 490 | { 491 | NSString *dispA = [UKTestHandler displayStringForObject: a]; 492 | NSString *dispB = [UKTestHandler displayStringForObject: b]; 493 | 494 | if ([a isEqualToString: b]) 495 | { 496 | NSString *msg = [UKTestHandler localizedString: @"msgUKStringsEqual.pass"]; 497 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 498 | 499 | [self reportStatus: YES inFile: filename line: line message: msg]; 500 | } 501 | else 502 | { 503 | NSString *msg = [UKTestHandler localizedString: @"msgUKStringsEqual.fail"]; 504 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 505 | 506 | [self reportStatus: NO inFile: filename line: line message: msg]; 507 | } 508 | } 509 | 510 | - (void)testString: (NSString *)a 511 | notEqualTo: (NSString *)b 512 | inFile: (const char *)filename 513 | line: (int)line 514 | { 515 | NSString *dispA = [UKTestHandler displayStringForObject: a]; 516 | NSString *dispB = [UKTestHandler displayStringForObject: b]; 517 | 518 | if (![a isEqualToString: b]) 519 | { 520 | NSString *msg = [UKTestHandler localizedString: @"msgUKStringsNotEqual.pass"]; 521 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 522 | 523 | [self reportStatus: YES inFile: filename line: line message: msg]; 524 | } 525 | else 526 | { 527 | NSString *msg = [UKTestHandler localizedString: @"msgUKStringsNotEqual.fail"]; 528 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 529 | 530 | [self reportStatus: NO inFile: filename line: line message: msg]; 531 | } 532 | } 533 | 534 | - (void)testString: (NSString *)a 535 | contains: (NSString *)b 536 | inFile: (const char *)filename 537 | line: (int)line 538 | { 539 | NSString *dispA = [UKTestHandler displayStringForObject: a]; 540 | NSString *dispB = [UKTestHandler displayStringForObject: b]; 541 | 542 | if ([a rangeOfString: b].location != NSNotFound) 543 | { 544 | NSString *msg = [UKTestHandler localizedString: @"msgUKStringContains.pass"]; 545 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 546 | 547 | [self reportStatus: YES inFile: filename line: line message: msg]; 548 | } 549 | else 550 | { 551 | NSString *msg = [UKTestHandler localizedString: @"msgUKStringContains.fail"]; 552 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 553 | 554 | [self reportStatus: NO inFile: filename line: line message: msg]; 555 | } 556 | } 557 | 558 | - (void)testString: (NSString *)a 559 | doesNotContain: (NSString *)b 560 | inFile: (const char *)filename 561 | line: (int)line 562 | { 563 | NSString *dispA = [UKTestHandler displayStringForObject: a]; 564 | NSString *dispB = [UKTestHandler displayStringForObject: b]; 565 | 566 | if ([a rangeOfString: b].location == NSNotFound) 567 | { 568 | NSString *msg = [UKTestHandler localizedString: @"msgUKStringDoesNotContain.pass"]; 569 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 570 | 571 | [self reportStatus: YES inFile: filename line: line message: msg]; 572 | } 573 | else 574 | { 575 | NSString *msg = [UKTestHandler localizedString: @"msgUKStringDoesNotContain.fail"]; 576 | msg = [NSString stringWithFormat: msg, dispA, dispB]; 577 | 578 | [self reportStatus: NO inFile: filename line: line message: msg]; 579 | } 580 | } 581 | 582 | #pragma mark - Exception Test Assertions 583 | 584 | - (void)raisesException: (NSException *)exception 585 | inFile: (const char *)filename 586 | line: (int)line 587 | { 588 | if (exception != nil) 589 | { 590 | NSString *msg = [UKTestHandler localizedString: @"msgUKExceptionRaised.pass"]; 591 | msg = [NSString stringWithFormat: msg, [[exception class] description]]; 592 | 593 | [self reportStatus: YES inFile: filename line: line message: msg]; 594 | } 595 | else 596 | { 597 | NSString *msg = [UKTestHandler localizedString: @"msgUKExecptionRaised.fail"]; 598 | 599 | [self reportStatus: NO inFile: filename line: line message: msg]; 600 | } 601 | } 602 | 603 | - (void)doesNotRaisesException: (NSException *)exception 604 | inFile: (const char *)filename 605 | line: (int)line 606 | { 607 | if (exception == nil) 608 | { 609 | NSString *msg = [UKTestHandler localizedString: @"msgUKExceptionNotRaised.pass"]; 610 | 611 | [self reportStatus: YES inFile: filename line: line message: msg]; 612 | } 613 | else 614 | { 615 | NSString *msg = [UKTestHandler localizedString: @"msgUKExceptionNotRaised.fail"]; 616 | msg = [NSString stringWithFormat: msg, [[exception class] description]]; 617 | 618 | [self reportStatus: NO inFile: filename line: line message: msg]; 619 | } 620 | } 621 | 622 | - (void)raisesException: (NSException *)exception 623 | named: (NSString *)expected 624 | inFile: (const char *)filename 625 | line: (int)line; 626 | { 627 | if (![exception isKindOfClass: [NSException class]]) 628 | { 629 | NSString *msg = [UKTestHandler localizedString: @"msgUKSpecificNSExceptionRaised.failNotNSException"]; 630 | msg = [NSString stringWithFormat: msg, exception.description]; 631 | 632 | [self reportStatus: NO inFile: filename line: line message: msg]; 633 | } 634 | else if ([exception.name isEqualToString: expected]) 635 | { 636 | NSString *msg = [UKTestHandler localizedString: @"msgUKSpecificNSExceptionRaised.pass"]; 637 | msg = [NSString stringWithFormat: msg, expected]; 638 | 639 | [self reportStatus: YES inFile: filename line: line message: msg]; 640 | } 641 | else 642 | { 643 | NSString *msg = [UKTestHandler localizedString: @"msgUKSpecificNSExceptionRaised.fail"]; 644 | msg = [NSString stringWithFormat: msg, expected, exception.name]; 645 | 646 | [self reportStatus: NO inFile: filename line: line message: msg]; 647 | } 648 | } 649 | 650 | - (void)raisesException: (id)raisedObject 651 | class: (Class)expectedClass 652 | inFile: (const char *)filename 653 | line: (int)line 654 | { 655 | if ([raisedObject isKindOfClass: expectedClass]) 656 | { 657 | NSString *msg = [UKTestHandler localizedString: @"msgUKRaisesSpecificClass.pass"]; 658 | msg = [NSString stringWithFormat: msg, [expectedClass description]]; 659 | 660 | [self reportStatus: YES inFile: filename line: line message: msg]; 661 | } 662 | else 663 | { 664 | NSString *msg = [UKTestHandler localizedString: @"msgUKRaisesSpecificClass.fail"]; 665 | msg = [NSString stringWithFormat: msg, [expectedClass description], 666 | [[raisedObject class] description]]; 667 | 668 | [self reportStatus: NO inFile: filename line: line message: msg]; 669 | } 670 | } 671 | 672 | @end 673 | -------------------------------------------------------------------------------- /FrameworkSource/UnitKit.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | #import 25 | -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | include $(GNUSTEP_MAKEFILES)/common.make 2 | 3 | SUBPROJECTS = ToolSource 4 | 5 | ifneq (,$(filter clean distclean,$(MAKECMDGOALS))) 6 | test ?= yes 7 | endif 8 | 9 | ifeq ($(test), yes) 10 | SUBPROJECTS += \ 11 | TestSource/TestFramework \ 12 | TestSource/TestBundle \ 13 | TestSource/TestUnitKit 14 | endif 15 | 16 | FRAMEWORK_NAME = UnitKit 17 | 18 | # ABI version (the API version is in CFBundleShortVersionString of FrameworkSource/Info.plist) 19 | UnitKit_VERSION = 1.5 20 | 21 | UnitKit_LIBRARIES_DEPEND_UPON = $(FND_LIBS) $(OBJC_LIBS) $(SYSTEM_LIBS) 22 | 23 | OTHER_HEADER_DIRS = FrameworkSource 24 | 25 | UnitKit_HEADER_FILES_DIR = UnitKit 26 | UnitKit_HEADER_FILES = $(notdir $(wildcard UnitKit/*.h)) 27 | 28 | UnitKit_OBJC_FILES = $(wildcard FrameworkSource/*.m) 29 | 30 | UnitKit_LOCALIZED_RESOURCE_FILES = UKTestHandler.strings 31 | UnitKit_LANGUAGES = English 32 | 33 | # Documentation 34 | 35 | UnitKitDoc_DOC_FILES = \ 36 | FrameworkSource/UKTest.h \ 37 | FrameworkSource/UKTestHandler.h \ 38 | FrameworkSource/UKRunner.h 39 | 40 | UnitKitDoc_MENU_TEMPLATE_FILE = Documentation/Templates/menu.html 41 | 42 | include compilerflags.preamble 43 | 44 | include $(GNUSTEP_MAKEFILES)/framework.make 45 | -include ../../etoile.make 46 | -include etoile.make 47 | -include ../../documentation.make 48 | include $(GNUSTEP_MAKEFILES)/aggregate.make 49 | 50 | # framework.make looks for xxxInfo.plist in the project directory only (xxx_RESOURCE_FILES is ignored). 51 | # framework.make looks for xxx_LOCALIZED_RESOURCE_FILES only in each language subdirectory (see Shared/bundle.make). 52 | before-all:: 53 | $(ECHO_NOTHING) \ 54 | if [ ! -e $(PROJECT_DIR)/UnitKitInfo.plist ]; then \ 55 | ln -s $(PROJECT_DIR)/FrameworkSource/Info.plist $(PROJECT_DIR)/UnitKitInfo.plist; \ 56 | ln -s $(PROJECT_DIR)/FrameworkSource/*.lproj $(PROJECT_DIR); \ 57 | fi; \ 58 | $(END_ECHO) 59 | 60 | after-clean:: 61 | rm -f $(PROJECT_DIR)/UnitKitInfo.plist $(PROJECT_DIR)/*.lproj 62 | -------------------------------------------------------------------------------- /INSTALL.Cocoa.md: -------------------------------------------------------------------------------- 1 | UnitKit Mac OS X and iOS INSTALL 2 | ================================ 3 | 4 | Required software 5 | ----------------- 6 | 7 | In addition to Xcode 4 or higher, you need Mac OS X 10.7 or higher to compile 8 | UnitKit. 9 | 10 | For test suites written with UnitKit, either Mac OS X 10.7 or higher, or iOS 7 11 | or higher are required to run them. 12 | 13 | 14 | Build and Install 15 | ----------------- 16 | 17 | For a simple build, open UnitKit.xcodeproj and choose ukrun in the Scheme menu. 18 | 19 | To install in /Library/Frameworks, do the build in the shell: 20 | 21 | sudo xcodebuild -target ukrun -configuration Release clean install 22 | 23 | 24 | Test suite (to test UnitKit with itself) 25 | ---------------------------------------- 26 | 27 | For runnings the tests that comes with UnitKit, open UnitKit.xcodeproj and 28 | choose TestUnitKit or TestUnitKit (iOS) in the Scheme menu. 29 | 30 | 31 | Trouble 32 | ------- 33 | 34 | Give us feedback! Tell us what you like; tell us what you think 35 | could be better. Send bug reports and patches with . 36 | -------------------------------------------------------------------------------- /INSTALL.GNUstep.md: -------------------------------------------------------------------------------- 1 | UnitKit 2 | ======= 3 | 4 | Required software 5 | ----------------- 6 | 7 | You need to have the GNUstep core libraries installed in order to 8 | compile and use UnitKit. The core packages are, at a minimum: 9 | 10 | * gnustep-make (recent release no older than a year) 11 | 12 | * gnustep-base (recent release no older than a year) 13 | 14 | See for further information. 15 | 16 | 17 | Build and Install 18 | ----------------- 19 | 20 | Square brackets "[ ]" are used to indicate optional parameters. 21 | 22 | Steps to build: 23 | 24 | make 25 | 26 | [sudo [-E]] make install 27 | 28 | 29 | Test suite (to test UnitKit with itself) 30 | ---------------------------------------- 31 | 32 | Square brackets "[ ]" are used to indicate optional parameters. 33 | 34 | To produce a test bundle and run the test suite: 35 | 36 | make test=yes 37 | 38 | ukrun [-q] TestSource/TestUnitKit/TestUnitKit.bundle 39 | 40 | 41 | Trouble 42 | ------- 43 | 44 | Give us feedback! Tell us what you like; tell us what you think 45 | could be better. Send bug reports and patches with . 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | UnitKit NEWS 2 | ============ 3 | 4 | 1.6 (CoreObject 0.6) 5 | -------------------- 6 | 7 | - Migrated to modern Objective-C and ARC 8 | - Support for large or unsigned integer types with UKIntsEqual() and UKIntsNotEqual() 9 | 10 | 1.5 (CoreObject 0.5) 11 | -------------------- 12 | 13 | - Added abstract test case support (test methods from superclasses are now run by UKRunner) 14 | - Added option to choose the tested classes (-c for a list based on a regex pattern) 15 | - Added uncaught exception reporting in the test results 16 | - Better reporting for uncaught exceptions in -init and -dealloc 17 | - Added class and method name printing in the test suite output 18 | - Added iOS support 19 | - Cleaned the code base and updated the documentation a lot 20 | - API documentation is now output with Etoile DocGenerator 21 | - Updated Xcode support 22 | - Added new Xcode file and project templates for Xcode 4 and higher 23 | - Removed dependency on AppKit and Growl notification support (nobody used it) 24 | - Removed -initForTest and -releasedForTest (proved to be a bad idea) 25 | 26 | 1.3 (Etoile 0.4) 27 | ---------------- 28 | 29 | - Added UKObjectKindOf test macro 30 | - Lazy instantiation of the application class if needed. This allows to test EtoileUI-based code which use ETApplication instead of NSApplication 31 | - Growl notifications on Mac OS X (borrowed from UnitKit 2.0 development that was never released) 32 | - More useful feedback when an exception is raised while performing a test 33 | - Fix for running the tests when NSProxy subclasses are present at runtime 34 | - Updated Xcode support 35 | 36 | 1.2 (Etoile 0.2) 37 | ---------------- 38 | 39 | - Memory leak fixes 40 | 41 | 1.1 (Etoile 0.1) 42 | ---------------- 43 | 44 | - Updated UnitKit 1.0 GNUstep port to UnitKit 1.1 source code 45 | - Test classes and test methods are now executed in alphabetical order 46 | - Test methods are now run within the scope of a run loop 47 | - Test class method support named like +testWhatever. 48 | - Added -initForTest and -releaseForTest as an alternative to -init and -dealloc 49 | 50 | 1.0 51 | --- 52 | 53 | - First GNUstep release (this is not the same release than the one on Mac OS X) 54 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | UnitKit was created by James Duncan Davidson and is now maintained by Quentin Mathe in the Etoile project. You can find out more about UnitKit at http://www.etoile-project.org/ 2 | 3 | Many people have given ideas, suggestions, and feedback to UnitKit. In particular Mike Clark, Joseph Heck, Glenn Vanderburg, and Daniel Steinberg provided feedback during the early development of UnitKit that materially shaped the current product. 4 | 5 | Michael Milvich contributed the initial NSException test macros, test handler code, and associated tests. 6 | 7 | Peter Johnson contributed information about how to run tests in the debugger and prompted a few changes to make debugging tests easier. 8 | 9 | Jonathan Wight contributed information helping to untangle the best way to test embeddeable frameworks. 10 | 11 | David Steinbrunner suggested many changes to both this manual and the example code that comes with UnitKit. 12 | 13 | Mark Dalrymple contributed quiet mode and fixed a bug with multiple test bundles not being executed correctly. 14 | 15 | Nicolas Roard contributed patches allowing for UnitKit to run under GNUstep. 16 | 17 | Christopther Armstrong contributed run loop improvements, exception logging, test class and method names printing in the test suite output, and an option to specify the classes to be tested. 18 | 19 | Eric Wasylishen contributed run loop improvements, better exception support, abstract test cases and an option to filter the classes to be tested based on a regex. 20 | 21 | Lundberg Johannes contributed new templates for Xcode 4 and higher. -------------------------------------------------------------------------------- /Package/Description.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IFPkgDescriptionTitle 6 | UnitKit 7 | 8 | 9 | -------------------------------------------------------------------------------- /Package/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleGetInfoString 6 | UnitKit 1.1 7 | CFBundleIndentifier 8 | net.x180.unitkit 9 | CFBundleName 10 | UnitKit 11 | CFBundleShortVersionString 12 | 1.1 13 | IFMajorVersion 14 | 0 15 | IFMinorVersion 16 | 9.5999999999999996 17 | IFPkgFlagAllowBackRev 18 | 19 | IFPkgFlagAuthorizationAction 20 | AdminAuthorization 21 | IFPkgFlagDefaultLocation 22 | / 23 | IFPkgFlagFollowLinks 24 | 25 | IFPkgFlagOverwritePermissions 26 | 27 | IFPkgFlagRestartAction 28 | NoRestart 29 | IFPkgFlagRootVolumeOnly 30 | 31 | IFPkgFormatVersion 32 | 0.11 33 | 34 | 35 | -------------------------------------------------------------------------------- /Package/Resources/License.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etoile/UnitKit/fd2bd2a9f05db78c50a8a6b49a39f97b8b095881/Package/Resources/License.txt -------------------------------------------------------------------------------- /Package/Resources/Readme.txt: -------------------------------------------------------------------------------- 1 | README PAGE -------------------------------------------------------------------------------- /Package/Resources/Welcome.txt: -------------------------------------------------------------------------------- 1 | WELCOME Page -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | UnitKit 2 | ======= 3 | 4 | Maintainer 5 | : Quentin Mathe 6 | Authors 7 | : James Duncan Davidson, Nicolas Roard, Quentin Mathe, David Chisnall, Yen-Ju Chen, Christopher Armstrong, Eric Wasylishen 8 | License 9 | : Apache License 2.0 (see LICENSE document) 10 | Version 11 | : 1.5 12 | 13 | [![Build Status](https://travis-ci.org/etoile/UnitKit.png?branch=master)](https://travis-ci.org/etoile/UnitKit) 14 | 15 | UnitKit is a minimalistic unit testing framework that supports Mac OS X, iOS and 16 | GNUstep. 17 | 18 | The framework is less than 2000 loc, and built around two classes UKRunner and 19 | UKTestHandler, plus some test macros, and an empty protocol UKTest to mark test 20 | classes. 21 | 22 | The UnitKit core features are: 23 | 24 | - Test assertion macros 25 | - easy to write and read 26 | - without useless arguments 27 | - not too many ones 28 | - extensible (implement a UKTestHandler subclass or category) 29 | - No test case class, just adopt UKTest protocol 30 | - No special methods -setUp and -tearDown, just implement -init and and -dealloc 31 | - Class test methods in addition to instance ones 32 | - Run loop integration for asynchronous testing 33 | - Uncaught exception reporting 34 | - Delegate methods to signal a test suite will start or just ended 35 | - Tested method and class choice based on a regex 36 | - Verbose and quiet ouput 37 | - Optional ukrun tool to run test suites packaged in test bundles 38 | - Xcode test suite templates 39 | 40 | To know more about UnitKit: 41 | 42 | 43 | **Note:** This UnitKit version is a fork of the original UnitKit written by 44 | James Duncan Davidson. The original version is not available anymore, and its 45 | development has been halted for many years. The initial project web site 46 | unitkit.org is also no longer available. 47 | 48 | 49 | Build and Install 50 | ----------------- 51 | 52 | Read INSTALL.Cocoa.md and INSTALL.GNUstep.md documents. 53 | 54 | 55 | Mac OS X support 56 | ---------------- 57 | 58 | Both Cocoa and Xcode support are actively maintained, and used by several 59 | Etoile modules that can be built on Mac OS X. 60 | 61 | 62 | How to use UnitKit with Mac OS X 63 | -------------------------------- 64 | 65 | You need to compile your sources as a bundle. If you have installed UnitKit 66 | as explained in INSTALL.Cocoa.md, with **File -> New -> Target...** Xcode should 67 | let you create a test bundle target/scheme. In the Xcode Template panel, choose 68 | **UnitKit Testing Bundle** available in the category **OS X -> Other**. 69 | 70 | For running the test suite, click Run in the toolbar. The scheme must 71 | have the tool set to 'ukrun' in the Run section, and the arguments to: 72 | 73 | - -q 74 | - $TARGET_BUILD_DIR/.bundle 75 | 76 | must be the test suite target/scheme name. You cannot use 77 | $TARGET_BUILD_DIR/$WRAPPER_NAME, because build settings variable are evaluated 78 | based on 'ukrun' and not based on the test suite build settings ('ukrun' is set 79 | as the executable in the Run section of the test suite scheme). 80 | 81 | If the UnitKit Testing Bundle template is used, this is is normally set up 82 | transparently. However it can be useful to check the scheme is correctly set up 83 | if the test suite doesn't run. 84 | 85 | Inside this bundle, compile the test classes and any additional code needed. 86 | 87 | For testing a framework or library, the test bundle can just link the tested 88 | product. 89 | 90 | **Note:** You can check TestUnitKit target and scheme to understand how to 91 | create a test bundle manually (without using the UnitKit Testing Bundle template). 92 | 93 | 94 | How to use UnitKit with iOS 95 | --------------------------- 96 | 97 | You need to compile your sources as an iOS application, since iOS doesn't let 98 | you run tools or create bundles. 99 | 100 | With **File -> New -> Target...** Xcode should let you create an application 101 | target/scheme. In the Xcode Template panel, choose **Empty Application** 102 | available in the category **iOS -> Application**. 103 | 104 | For the new target, you should now just keep Info.plist, all the other files 105 | created by Xcode can be removed (e.g. main.m, AppDelegate.h, AppDelegate.m, 106 | Prefix.h, localization files and the directory that corresponds to the target on 107 | disk). 108 | 109 | Finally copy UnitKit/Source/iOSCompatibility/main.m in your project, and this 110 | file to the new target. Based on the UnitKit API, main.m can be customized to 111 | control the tested classes, the verbosity etc. 112 | 113 | For running the test suite, click Run in the toolbar. 114 | 115 | Inside this test application, compile the test classes and any additional code 116 | needed. 117 | 118 | For testing a framework or library, the application can just link the tested 119 | product. 120 | 121 | **Note:** You can check TestUnitKit (iOS) target and scheme to understand how to 122 | create a iOS test application manually. 123 | 124 | 125 | How to use UnitKit with GNUstep Make 126 | ------------------------------------ 127 | 128 | You need to compile your sources as a bundle. Here is a GNUmakefile example: 129 | 130 | include $(GNUSTEP_MAKEFILES)/common.make 131 | 132 | BUNDLE_NAME = Test 133 | Test_OBJC_FILES = # your sources and test classes... 134 | Test_OBJC_LIBS = -lUnitKit # you can link a tested library or framework 135 | 136 | include $(GNUSTEP_MAKEFILES)/bundle.make 137 | 138 | Then, just type: 139 | 140 | ukrun Test.bundle 141 | 142 | And you should have the list of the tests and their status. You can omit the 143 | 'Test.bundle' argument, if you do so 'ukrun' will try to run any bundles (with 144 | .bundle extension) located in the current directory. 145 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | UnitKit TODO 2 | ============ 3 | 4 | - Perhaps change test bundle extension from 'bundle' to 'testbundle' or 'unitkit' 5 | 6 | - Declare implicit UKTestHandlerDelegate informal protocol 7 | 8 | - Move UKRunner tool support to a dedicated class UKTool or UKBundleLoader 9 | 10 | - Perhaps change the UKRunner API for running tests and adding test classes to: -addTestClassesNames:, -addTestClassesFromBundle: and -runWithPrincipalClass:. 11 | 12 | - Add -[UKRunner initWithHandler:] and retrieve the test handler in test macros with [[UKRunner runnerForObject: self] handler] 13 | 14 | - we could maintain a map of runners by test object, or just attach the runner with a 'UKRunner' associated reference 15 | - this would make possible to support handler subclasses cleanly and multiple simultaneous runners (each one using their own custom handler) 16 | 17 | - Support parameterized test class instantiation, the same test class being instantiated multiple times with various arguments (passed in a dictionary or an array) 18 | 19 | - the test class could implement an optional informal protocol that returns a collection containing each instantiation arguments (the collection element represent all the expected instantiatations) 20 | 21 | - Resurrect the old UnitTests utility, see http://svn.gna.org/viewcvs/etoile/trunk/Etoile/Developer/Services/UnitTests/ 22 | 23 | -------------------------------------------------------------------------------- /TestSource/TestBundle/GNUmakefile: -------------------------------------------------------------------------------- 1 | include $(GNUSTEP_MAKEFILES)/common.make 2 | 3 | PRINT_PROJECT_NAME = NO 4 | 5 | BUNDLE_NAME = TestBundle 6 | 7 | $(BUNDLE_NAME)_BUNDLE_LIBS = -lUnitKit $(FND_LIBS) 8 | 9 | $(BUNDLE_NAME)_HEADER_FILES = TestOne.h TestTwo.h TestThree.h 10 | 11 | $(BUNDLE_NAME)_OBJC_FILES = TestOne.m TestTwo.m TestThree.m 12 | 13 | include ../../compilerflags.preamble 14 | 15 | include $(GNUSTEP_MAKEFILES)/bundle.make 16 | -include ../../../../etoile.make 17 | -include ../../etoile.make 18 | -------------------------------------------------------------------------------- /TestSource/TestBundle/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | ${CURRENT_MARKETING_VERSION} 19 | CFBundleSignature 20 | ???? 21 | 22 | 23 | -------------------------------------------------------------------------------- /TestSource/TestBundle/TestOne.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | /** 26 | * This class is not marked so that it won't be picked up by UKRunner 27 | * on a search through. This is on purpose. 28 | */ 29 | @interface TestOne : NSObject 30 | { 31 | 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /TestSource/TestBundle/TestOne.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "TestOne.h" 23 | 24 | @implementation TestOne 25 | 26 | - (void)testOne 27 | { 28 | UKPass(); 29 | } 30 | 31 | - (void)testTwo 32 | { 33 | UKFail(); 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /TestSource/TestBundle/TestThree.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | @interface TestThree : NSObject 26 | { 27 | 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /TestSource/TestBundle/TestThree.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "TestThree.h" 23 | 24 | @implementation TestThree 25 | 26 | + (void)testClass 27 | { 28 | UKPass(); 29 | } 30 | 31 | + (void)testClass1 32 | { 33 | UKPass(); 34 | } 35 | 36 | - (void)testOne 37 | { 38 | UKPass(); 39 | } 40 | 41 | - (void)testTwo 42 | { 43 | UKPass(); 44 | } 45 | 46 | - (void)testThree 47 | { 48 | UKPass(); 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /TestSource/TestBundle/TestTwo.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | @interface TestTwo : NSObject 26 | { 27 | 28 | } 29 | 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /TestSource/TestBundle/TestTwo.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "TestTwo.h" 23 | 24 | @implementation TestTwo 25 | 26 | + (void)testClass 27 | { 28 | UKPass(); 29 | } 30 | 31 | - (void)testOne 32 | { 33 | UKPass(); 34 | } 35 | 36 | - (void)testTwo 37 | { 38 | UKPass(); 39 | } 40 | 41 | - (void)testThree 42 | { 43 | UKPass(); 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /TestSource/TestFramework/GNUmakefile: -------------------------------------------------------------------------------- 1 | include $(GNUSTEP_MAKEFILES)/common.make 2 | 3 | # We reset PROJECT_DIR provided by etoile.make to match the subproject since 4 | # etoile.make doesn't detect and handle such embedded project (this ensures 5 | # the headers and framework get exported in the Build directory and can be 6 | # found by TestBundle) 7 | PROJECT_DIR = $(CURDIR) 8 | PRINT_PROJECT_NAME = NO 9 | 10 | FRAMEWORK_NAME = TestFramework 11 | # We declare PROJECT_NAME to export the dependencies (see etoile.make) 12 | PROJECT_NAME = $(FRAMEWORK_NAME) 13 | 14 | $(FRAMEWORK_NAME)_LIBRARIES_DEPEND_UPON = -lUnitKit $(FND_LIBS) 15 | 16 | $(FRAMEWORK_NAME)_HEADER_FILES = TestClass.h 17 | 18 | $(FRAMEWORK_NAME)_OBJC_FILES = TestClass.m 19 | 20 | include ../../compilerflags.preamble 21 | 22 | include $(GNUSTEP_MAKEFILES)/framework.make 23 | -include ../../../../etoile.make 24 | -include ../../etoile.make 25 | -------------------------------------------------------------------------------- /TestSource/TestFramework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | FMWK 15 | CFBundleSignature 16 | ???? 17 | 18 | 19 | -------------------------------------------------------------------------------- /TestSource/TestFramework/TestClass.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | 24 | @interface TestClass : NSObject 25 | { 26 | 27 | } 28 | 29 | - (int)testMethod; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /TestSource/TestFramework/TestClass.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "TestClass.h" 23 | 24 | @implementation TestClass 25 | 26 | - (int)testMethod 27 | { 28 | return 42; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/GNUmakefile: -------------------------------------------------------------------------------- 1 | include $(GNUSTEP_MAKEFILES)/common.make 2 | 3 | PRINT_PROJECT_NAME = NO 4 | 5 | BUNDLE_NAME = TestUnitKit 6 | 7 | # For running the test suite without installing TestFramework 8 | $(BUNDLE_NAME)_LDFLAGS = -Wl,-rpath=$(BUILD_DIR) 9 | $(BUNDLE_NAME)_NEEDS_GUI = no 10 | 11 | $(BUNDLE_NAME)_BUNDLE_LIBS = -lUnitKit -lTestFramework $(FND_LIBS) 12 | 13 | $(BUNDLE_NAME)_OBJC_FILES = $(wildcard *.m) 14 | 15 | include ../../compilerflags.preamble 16 | 17 | include $(GNUSTEP_MAKEFILES)/bundle.make 18 | -include ../../../../etoile.make 19 | -include ../../etoile.make 20 | 21 | export TEST_BUNDLE_PATH = $(PROJECT_DIR)/TestSource/TestBundle/TestBundle.bundle 22 | export TEST_BUNDLE_LINK_PATH = $(PROJECT_DIR)/TestSource/TestUnitKit/TestBundle.bundle 23 | 24 | after-all:: 25 | $(ECHO_NOTHING) \ 26 | if [ ! -e $(TEST_BUNDLE_LINK_PATH) ]; then \ 27 | ln -s $(TEST_BUNDLE_PATH) $(TEST_BUNDLE_LINK_PATH); \ 28 | fi; \ 29 | $(END_ECHO) 30 | 31 | after-clean:: 32 | rm -f $(TEST_BUNDLE_LINK_PATH) 33 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | ${CURRENT_MARKETING_VERSION} 19 | CFBundleSignature 20 | ???? 21 | 22 | 23 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/TestObject.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) 2014 Quentin Mathe 3 | 4 | Date: January 2014 5 | License: Apache License, Version 2.0 (see COPYING) 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | @interface TestObject : NSObject 12 | @end 13 | 14 | @interface TestObjectInit : TestObject 15 | @end 16 | 17 | @interface TestObjectDealloc : TestObject 18 | @end 19 | 20 | @interface TestObjectTestMethod : TestObject 21 | @end -------------------------------------------------------------------------------- /TestSource/TestUnitKit/TestObject.m: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) 2014 Quentin Mathe 3 | 4 | Date: January 2014 5 | License: Apache License, Version 2.0 (see COPYING) 6 | */ 7 | 8 | #import "TestObject.h" 9 | 10 | @implementation TestObject 11 | 12 | - (void)testEmpty 13 | { 14 | 15 | } 16 | 17 | @end 18 | 19 | 20 | @implementation TestObjectInit 21 | 22 | - (instancetype)init 23 | { 24 | self = [super init]; 25 | if (self == nil) 26 | return nil; 27 | 28 | [NSException raise: @"Test" format: @"For exception in init"]; 29 | return self; 30 | } 31 | 32 | @end 33 | 34 | 35 | @implementation TestObjectDealloc 36 | 37 | - (void)dealloc 38 | { 39 | [NSException raise: @"Test" format: @"For exception in dealloc"]; 40 | } 41 | 42 | @end 43 | 44 | 45 | @implementation TestObjectTestMethod 46 | 47 | - (void)testRaisesException 48 | { 49 | [NSException raise: @"Test" format: @"For exception in test method"]; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKRunnerTests.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson, Quentin Mathe 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | /** 26 | * Testing a test runner is a bit of a funky proposition. After all, it's a 27 | * snake eating its tail kind of affair. However, it's done here by testing out 28 | * the most critical functionality of the class--finding the test classes in a 29 | * bundle and the test methods in a class--as well as running a test bundle 30 | * from the outside and examining its output. Even though this isn't as fine 31 | * grained a testing strategy as one might like, it will catch everything we 32 | * need to catch. And hey, if the runner isn't working, then these tests won't 33 | * even be run, right??? :) 34 | */ 35 | @interface UKRunnerTests : NSObject 36 | { 37 | NSBundle *testBundle; 38 | UKTestHandler *handler; 39 | NSException *reportedException; 40 | Class reportedTestClass; 41 | NSString *reportedMethodName; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKRunnerTests.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson, Quentin Mathe 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "UKRunnerTests.h" 23 | #import "TestObject.h" 24 | 25 | @interface RandomObject : NSObject 26 | @end 27 | 28 | @implementation RandomObject 29 | 30 | static BOOL randomObjectInitialized = NO; 31 | 32 | + (void)initialize 33 | { 34 | randomObjectInitialized = YES; 35 | } 36 | 37 | @end 38 | 39 | @interface TestedObject : NSObject 40 | @end 41 | 42 | @implementation TestedObject 43 | 44 | static BOOL testedObjectInitialized = NO; 45 | 46 | + (void)initialize 47 | { 48 | testedObjectInitialized = YES; 49 | } 50 | 51 | @end 52 | 53 | @implementation UKRunnerTests 54 | 55 | - (id)init 56 | { 57 | self = [super init]; 58 | if (self == nil) 59 | return nil; 60 | 61 | handler = [UKTestHandler handler]; 62 | 63 | #if !(TARGET_OS_IPHONE) 64 | NSString *mainTestBundlePath = [NSBundle bundleForClass: [self class]].bundlePath; 65 | NSString *testBundlePath = [[mainTestBundlePath stringByDeletingLastPathComponent] 66 | stringByAppendingPathComponent: @"TestBundle.bundle"]; 67 | 68 | testBundle = [[NSBundle alloc] initWithPath: testBundlePath]; 69 | NSAssert1(testBundle != nil, @"Found not test bundle at %@", testBundlePath); 70 | [testBundle load]; 71 | #endif 72 | 73 | return self; 74 | } 75 | 76 | - (void)reportException: (NSException *)exception 77 | inClass: (Class)testClass 78 | hint: (NSString *)hint 79 | { 80 | reportedException = exception; 81 | reportedTestClass = testClass; 82 | reportedMethodName = hint; 83 | } 84 | 85 | - (void)testRunLoopAddition 86 | { 87 | NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 88 | [runLoop performSelector: @selector(runLoopTrigger) 89 | target: self 90 | argument: nil 91 | order: 0 92 | modes: @[NSDefaultRunLoopMode]]; 93 | } 94 | 95 | - (void)runLoopTrigger 96 | { 97 | NSThread *thread = [NSThread currentThread]; 98 | thread.threadDictionary[@"UKLoopTriggerRan"] = @"YES"; 99 | } 100 | 101 | - (void)testRunLoopAdditionExecuted 102 | { 103 | NSThread *thread = [NSThread currentThread]; 104 | NSString *result = thread.threadDictionary[@"UKLoopTriggerRan"]; 105 | 106 | UKStringsEqual(result, @"YES"); 107 | 108 | [thread.threadDictionary removeObjectForKey: @"UKLoopTriggerRan"]; 109 | } 110 | 111 | - (void)testRunLoopMode 112 | { 113 | NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 114 | UKStringsEqual([runLoop currentMode], NSDefaultRunLoopMode); 115 | 116 | } 117 | 118 | #if !(TARGET_OS_IPHONE) 119 | 120 | - (void)testClassesFromBundle 121 | { 122 | NSArray *testClasses = UKTestClassNamesFromBundle(testBundle); 123 | 124 | UKIntsEqual(2, [testClasses count]); 125 | UKTrue([testClasses containsObject: @"TestTwo"]); 126 | UKTrue([testClasses containsObject: @"TestThree"]); 127 | 128 | UKFalse(randomObjectInitialized); 129 | #ifdef GNUSTEP 130 | UKFalse(testedObjectInitialized); 131 | #else 132 | UKTrue(testedObjectInitialized); 133 | #endif 134 | } 135 | 136 | #endif 137 | 138 | - (void)testMethodNamesFromClass 139 | { 140 | NSArray *testMethods = UKTestMethodNamesFromClass(NSClassFromString(@"TestTwo")); 141 | 142 | UKIntsEqual(3, [testMethods count]); 143 | UKTrue([testMethods containsObject: @"testOne"]); 144 | UKTrue([testMethods containsObject: @"testTwo"]); 145 | UKTrue([testMethods containsObject: @"testThree"]); 146 | } 147 | 148 | - (void)testReportInitException 149 | { 150 | UKRunner *runner = [[UKRunner alloc] init]; 151 | [handler setDelegate: self]; 152 | 153 | UKDoesNotRaiseException([runner runTests: @[@"testEmpty"] 154 | onInstance: YES 155 | ofClass: [TestObjectInit class]]); 156 | 157 | UKStringsEqual(@"For exception in init", reportedException.reason); 158 | UKObjectsEqual([TestObjectInit class], reportedTestClass); 159 | UKStringsEqual(@"errExceptionOnInit", reportedMethodName); 160 | 161 | handler.delegate = nil; 162 | } 163 | 164 | - (void)testReportDeallocException 165 | { 166 | UKRunner *runner = [[UKRunner alloc] init]; 167 | [handler setDelegate: self]; 168 | 169 | UKDoesNotRaiseException([runner runTests: @[@"testEmpty"] 170 | onInstance: YES 171 | ofClass: [TestObjectDealloc class]]); 172 | 173 | UKStringsEqual(@"For exception in dealloc", reportedException.reason); 174 | UKObjectsEqual([TestObjectDealloc class], reportedTestClass); 175 | UKStringsEqual(@"errExceptionOnRelease", reportedMethodName); 176 | 177 | handler.delegate = nil; 178 | } 179 | 180 | - (void)testReportTestMethodException 181 | { 182 | UKRunner *runner = [[UKRunner alloc] init]; 183 | [handler setDelegate: self]; 184 | 185 | UKDoesNotRaiseException([runner runTests: @[@"testRaisesException"] 186 | onInstance: YES 187 | ofClass: [TestObjectTestMethod class]]); 188 | 189 | UKStringsEqual(@"For exception in test method", reportedException.reason); 190 | UKObjectsEqual([TestObjectTestMethod class], reportedTestClass); 191 | UKStringsEqual(@"testRaisesException", reportedMethodName); 192 | 193 | handler.delegate = nil; 194 | } 195 | 196 | /* 197 | - (void) testBundleInOutsideExecution 198 | { 199 | NSString *ukrunPath = [[[NSFileManager defaultManager] currentDirectoryPath] stringByAppendingPathComponent:@"ukrun"]; 200 | UKTask *task = [[UKTask alloc] init]; 201 | [task setLaunchPath:ukrunPath]; 202 | [task setArguments:[NSArray arrayWithObjects:[[[NSFileManager defaultManager] currentDirectoryPath] stringByAppendingPathComponent:@"TestBundle.bundle"], nil]]; 203 | [task run]; 204 | 205 | // task run should fail... 206 | UKIntsEqual(255, [task terminationStatus]); 207 | NSArray *outputLines = [[task standardOutput] componentsSeparatedByString:@"\n"]; 208 | 209 | // 6 lines from tests, 1 line of summary, 1 empty line at end 210 | UKIntsEqual(8, [outputLines count]); 211 | 212 | // XXX sometime get around to testing other lines. But we're seeing it 213 | // all work well enough in Xcode that I think it's ok for now... 214 | 215 | // test last line of output 216 | UKStringsEqual(@"Result: 2 classes, 6 methods, 6 tests, 1 failed", 217 | [outputLines objectAtIndex:6]); 218 | 219 | [task release]; 220 | } 221 | */ 222 | @end 223 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKTestFileNames.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | /** 26 | * Tests to make sure that the file names reported by the various macros make 27 | * it through the macro and through the test handler methods in UKTestHandler. 28 | * This is done by setting this class to be the UKTestHandler's delegate, 29 | * performing a test, and then setting the UKTestHandler's delegeate to nil so 30 | * that the normal reporting mechanism is back in place. 31 | * 32 | * Because the code paths in the various test methods are conditional, both 33 | * positive and negative tests are performed on each macro. 34 | */ 35 | @interface UKTestFileNames : NSObject 36 | { 37 | UKTestHandler *handler; 38 | NSString *reportedFilename; 39 | NSString *actualFilename; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKTestFileNames.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "UKTestFileNames.h" 23 | 24 | @implementation UKTestFileNames 25 | 26 | - (instancetype)init 27 | { 28 | self = [super init]; 29 | if (self == nil) 30 | return nil; 31 | 32 | handler = [UKTestHandler handler]; 33 | handler.delegate = self; 34 | actualFilename = [[NSString alloc] initWithCString: __FILE__ 35 | encoding: NSUTF8StringEncoding]; 36 | return self; 37 | } 38 | 39 | - (void)reportStatus: (BOOL)cond 40 | inFile: (char *)filename 41 | line: (int)line 42 | message: (NSString *)msg 43 | { 44 | reportedFilename = [[NSString alloc] initWithCString: filename 45 | encoding: NSUTF8StringEncoding]; 46 | } 47 | 48 | - (void)testUKPass 49 | { 50 | UKPass(); 51 | handler.delegate = nil; 52 | UKStringsEqual(actualFilename, reportedFilename); 53 | } 54 | 55 | - (void)testUKFail 56 | { 57 | UKFail(); 58 | handler.delegate = nil; 59 | UKStringsEqual(actualFilename, reportedFilename); 60 | } 61 | 62 | - (void)testUKTrue 63 | { 64 | UKTrue(YES); 65 | handler.delegate = nil; 66 | UKStringsEqual(actualFilename, reportedFilename); 67 | } 68 | 69 | - (void)testUKTrue_Negative 70 | { 71 | UKTrue(NO); 72 | handler.delegate = nil; 73 | UKStringsEqual(actualFilename, reportedFilename); 74 | } 75 | 76 | - (void)testUKFalse 77 | { 78 | UKFalse(NO); 79 | handler.delegate = nil; 80 | UKStringsEqual(actualFilename, reportedFilename); 81 | } 82 | 83 | - (void)testUKFalse_Negative 84 | { 85 | UKFalse(YES); 86 | handler.delegate = nil; 87 | UKStringsEqual(actualFilename, reportedFilename); 88 | } 89 | 90 | - (void)testUKNil 91 | { 92 | UKNil(nil); 93 | handler.delegate = nil; 94 | UKStringsEqual(actualFilename, reportedFilename); 95 | } 96 | 97 | - (void)testUKNil_Negative 98 | { 99 | UKNil(@""); 100 | handler.delegate = nil; 101 | UKStringsEqual(actualFilename, reportedFilename); 102 | } 103 | 104 | - (void)testUKNotNil 105 | { 106 | UKNotNil(@""); 107 | handler.delegate = nil; 108 | UKStringsEqual(actualFilename, reportedFilename); 109 | } 110 | 111 | - (void)testUKNotNil_Negative 112 | { 113 | UKNotNil(nil); 114 | handler.delegate = nil; 115 | UKStringsEqual(actualFilename, reportedFilename); 116 | } 117 | 118 | - (void)testUKIntsEqual 119 | { 120 | UKIntsEqual(1, 1); 121 | handler.delegate = nil; 122 | UKStringsEqual(actualFilename, reportedFilename); 123 | } 124 | 125 | - (void)testUKIntsEqual_Negative 126 | { 127 | UKIntsEqual(1, 2); 128 | handler.delegate = nil; 129 | UKStringsEqual(actualFilename, reportedFilename); 130 | } 131 | 132 | - (void)testUKFloatsEqual 133 | { 134 | UKFloatsEqual(1.0, 1.0, 0.1); 135 | handler.delegate = nil; 136 | UKStringsEqual(actualFilename, reportedFilename); 137 | } 138 | 139 | - (void)testUKFloatsEqual_Negative 140 | { 141 | UKFloatsEqual(1.0, 2.0, 0.1); 142 | handler.delegate = nil; 143 | UKStringsEqual(actualFilename, reportedFilename); 144 | } 145 | 146 | - (void)testUKFloatsNotEqual 147 | { 148 | UKFloatsNotEqual(1.0, 2.0, 0.1); 149 | handler.delegate = nil; 150 | UKStringsEqual(actualFilename, reportedFilename); 151 | } 152 | 153 | - (void)testUKFloatsNotEqual_Negative 154 | { 155 | UKFloatsNotEqual(1.0, 1.0, 0.1); 156 | handler.delegate = nil; 157 | UKStringsEqual(actualFilename, reportedFilename); 158 | } 159 | 160 | - (void)testUKObjectsEqual 161 | { 162 | UKObjectsEqual(self, self); 163 | handler.delegate = nil; 164 | UKStringsEqual(actualFilename, reportedFilename); 165 | } 166 | 167 | - (void)testUKObjectsEqual_Negative 168 | { 169 | UKObjectsEqual(self, @"asdf"); 170 | handler.delegate = nil; 171 | UKStringsEqual(actualFilename, reportedFilename); 172 | } 173 | 174 | - (void)testUKObjectsSame 175 | { 176 | UKObjectsSame(self, self); 177 | handler.delegate = nil; 178 | UKStringsEqual(actualFilename, reportedFilename); 179 | } 180 | 181 | - (void)testUKObjectsSame_Negative 182 | { 183 | UKObjectsSame(self, @"asdf"); 184 | handler.delegate = nil; 185 | UKStringsEqual(actualFilename, reportedFilename); 186 | } 187 | 188 | - (void)testUKStringsEqual 189 | { 190 | UKStringsEqual(@"a", @"a"); 191 | handler.delegate = nil; 192 | UKStringsEqual(actualFilename, reportedFilename); 193 | } 194 | 195 | - (void)testUKStringsEqual_Negative 196 | { 197 | UKStringsEqual(@"a", @"b"); 198 | handler.delegate = nil; 199 | UKStringsEqual(actualFilename, reportedFilename); 200 | } 201 | 202 | - (void)testUKStringContains 203 | { 204 | UKStringContains(@"Now is the time", @"the time"); 205 | handler.delegate = nil; 206 | UKStringsEqual(actualFilename, reportedFilename); 207 | } 208 | 209 | - (void)testUKStringContains_Negative 210 | { 211 | UKStringContains(@"asdf", @"zzzzz"); 212 | handler.delegate = nil; 213 | UKStringsEqual(actualFilename, reportedFilename); 214 | } 215 | 216 | - (void)testUKStringDoesNotContain 217 | { 218 | UKStringDoesNotContain(@"asdf", @"zzzzz"); 219 | handler.delegate = nil; 220 | UKStringsEqual(actualFilename, reportedFilename); 221 | } 222 | 223 | - (void)testUKStringDoesNotContain_Negative 224 | { 225 | UKStringDoesNotContain(@"Now is the time", @"the time"); 226 | handler.delegate = nil; 227 | UKStringsEqual(actualFilename, reportedFilename); 228 | } 229 | 230 | 231 | @end 232 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKTestFramework.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | @interface UKTestFramework : NSObject 26 | { 27 | 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKTestFramework.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "UKTestFramework.h" 23 | #import 24 | 25 | @implementation UKTestFramework 26 | 27 | - (void)testClass 28 | { 29 | TestClass *instance = [[TestClass alloc] init]; 30 | UKIntsEqual([instance testMethod], 42); 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKTestLineNumbers.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | /** 26 | * Tests to make sure that the line numbers reported by the various macros make 27 | * it through the macro and through the test handler methods in UKTestHandler. 28 | * This is done by setting this class to be the UKTestHandler's delegate, 29 | * performing a test, and then setting the UKTestHandler's delegeate to nil so 30 | * that the normal reporting mechanism is back in place. 31 | * 32 | * Because the code paths in the various test methods are conditional, both 33 | * positive and negative tests are performed on each macro. 34 | */ 35 | @interface UKTestLineNumbers : NSObject 36 | { 37 | UKTestHandler *handler; 38 | int reportedLine; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKTestLineNumbers.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "UKTestLineNumbers.h" 23 | 24 | @implementation UKTestLineNumbers 25 | 26 | - (instancetype)init 27 | { 28 | self = [super init]; 29 | if (self == nil) 30 | return nil; 31 | 32 | handler = [UKTestHandler handler]; 33 | handler.delegate = self; 34 | return self; 35 | } 36 | 37 | - (void)reportStatus: (BOOL)cond 38 | inFile: (char *)filename 39 | line: (int)line 40 | message: (NSString *)msg 41 | { 42 | reportedLine = line; 43 | } 44 | 45 | - (void)testUKPass 46 | { 47 | UKPass(); 48 | handler.delegate = nil; 49 | UKIntsEqual((__LINE__ - 2), reportedLine); 50 | } 51 | 52 | - (void)testUKFail 53 | { 54 | UKFail(); 55 | handler.delegate = nil; 56 | UKIntsEqual((__LINE__ - 2), reportedLine); 57 | } 58 | 59 | - (void)testUKTrue 60 | { 61 | UKTrue(YES); 62 | handler.delegate = nil; 63 | UKIntsEqual((__LINE__ - 2), reportedLine); 64 | } 65 | 66 | - (void)testUKTrue_Negative 67 | { 68 | UKTrue(NO); 69 | handler.delegate = nil; 70 | UKIntsEqual((__LINE__ - 2), reportedLine); 71 | } 72 | 73 | - (void)testUKFalse 74 | { 75 | UKFalse(NO); 76 | handler.delegate = nil; 77 | UKIntsEqual((__LINE__ - 2), reportedLine); 78 | } 79 | 80 | - (void)testUKFalse_Negative 81 | { 82 | UKFalse(YES); 83 | handler.delegate = nil; 84 | UKIntsEqual((__LINE__ - 2), reportedLine); 85 | } 86 | 87 | - (void)testUKNil 88 | { 89 | UKNil(nil); 90 | handler.delegate = nil; 91 | UKIntsEqual((__LINE__ - 2), reportedLine); 92 | } 93 | 94 | - (void)testUKNil_Negative 95 | { 96 | UKNil(@""); 97 | handler.delegate = nil; 98 | UKIntsEqual((__LINE__ - 2), reportedLine); 99 | } 100 | 101 | - (void)testUKNotNil 102 | { 103 | UKNotNil(@""); 104 | handler.delegate = nil; 105 | UKIntsEqual((__LINE__ - 2), reportedLine); 106 | } 107 | 108 | - (void)testUKNotNil_Negative 109 | { 110 | UKNotNil(nil); 111 | handler.delegate = nil; 112 | UKIntsEqual((__LINE__ - 2), reportedLine); 113 | } 114 | 115 | - (void)testUKIntsEqual 116 | { 117 | UKIntsEqual(1, 1); 118 | handler.delegate = nil; 119 | UKIntsEqual((__LINE__ - 2), reportedLine); 120 | } 121 | 122 | - (void)testUKIntsEqual_Negative 123 | { 124 | UKIntsEqual(1, 2); 125 | handler.delegate = nil; 126 | UKIntsEqual((__LINE__ - 2), reportedLine); 127 | } 128 | 129 | - (void)testUKFloatsEqual 130 | { 131 | UKFloatsEqual(1.0, 1.0, 0.1); 132 | handler.delegate = nil; 133 | UKIntsEqual((__LINE__ - 2), reportedLine); 134 | } 135 | 136 | - (void)testUKFloatsEqual_Negative 137 | { 138 | UKFloatsEqual(1.0, 2.0, 0.1); 139 | handler.delegate = nil; 140 | UKIntsEqual((__LINE__ - 2), reportedLine); 141 | } 142 | 143 | - (void)testUKFloatsNotEqual 144 | { 145 | UKFloatsNotEqual(1.0, 2.0, 0.1); 146 | handler.delegate = nil; 147 | UKIntsEqual((__LINE__ - 2), reportedLine); 148 | } 149 | 150 | - (void)testUKFloatsNotEqual_Negative 151 | { 152 | UKFloatsNotEqual(1.0, 1.0, 0.1); 153 | handler.delegate = nil; 154 | UKIntsEqual((__LINE__ - 2), reportedLine); 155 | } 156 | 157 | - (void)testUKObjectsEqual 158 | { 159 | UKObjectsEqual(self, self); 160 | handler.delegate = nil; 161 | UKIntsEqual((__LINE__ - 2), reportedLine); 162 | } 163 | 164 | - (void)testUKObjectsEqual_Negative 165 | { 166 | UKObjectsEqual(self, @"asdf"); 167 | handler.delegate = nil; 168 | UKIntsEqual((__LINE__ - 2), reportedLine); 169 | } 170 | 171 | - (void)testUKObjectsSame 172 | { 173 | UKObjectsSame(self, self); 174 | handler.delegate = nil; 175 | UKIntsEqual((__LINE__ - 2), reportedLine); 176 | } 177 | 178 | - (void)testUKObjectsSame_Negative 179 | { 180 | UKObjectsSame(self, @"asdf"); 181 | handler.delegate = nil; 182 | UKIntsEqual((__LINE__ - 2), reportedLine); 183 | } 184 | 185 | - (void)testUKStringsEqual 186 | { 187 | UKStringsEqual(@"a", @"a"); 188 | handler.delegate = nil; 189 | UKIntsEqual((__LINE__ - 2), reportedLine); 190 | } 191 | 192 | - (void)testUKStringsEqual_Negative 193 | { 194 | UKStringsEqual(@"a", @"b"); 195 | handler.delegate = nil; 196 | UKIntsEqual((__LINE__ - 2), reportedLine); 197 | } 198 | 199 | - (void)testUKStringContains 200 | { 201 | UKStringContains(@"Now is the time", @"the time"); 202 | handler.delegate = nil; 203 | UKIntsEqual((__LINE__ - 2), reportedLine); 204 | } 205 | 206 | - (void)testUKStringContains_Negative 207 | { 208 | UKStringContains(@"asdf", @"zzzzz"); 209 | handler.delegate = nil; 210 | UKIntsEqual((__LINE__ - 2), reportedLine); 211 | } 212 | 213 | - (void)testUKStringDoesNotContain 214 | { 215 | UKStringDoesNotContain(@"asdf", @"zzzzz"); 216 | handler.delegate = nil; 217 | UKIntsEqual((__LINE__ - 2), reportedLine); 218 | } 219 | 220 | - (void)testUKStringDoesNotContain_Negative 221 | { 222 | UKStringDoesNotContain(@"Now is the time", @"the time"); 223 | handler.delegate = nil; 224 | UKIntsEqual((__LINE__ - 2), reportedLine); 225 | } 226 | 227 | @end 228 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKTestMacros.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson, Michael Milvich 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | /** 26 | * Exercise the various values that can be fed through each of the macros. In 27 | * this test class, we are only concerned about the pass or fail status. We have 28 | * other classes to test whether or not the line numbers and filenames make it 29 | * through. 30 | * 31 | * Because this class deals with the very heart of the test mechanism, a few of 32 | * the tests also contain NSAssert statements so that if things go very wrong 33 | * there will be something to indicate what's going on. 34 | */ 35 | @interface UKTestMacros : NSObject 36 | { 37 | UKTestHandler *handler; 38 | BOOL reportedStatus; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKTestMacros.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson, Michael Milvich 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | #import "UKTestMacros.h" 22 | 23 | @implementation UKTestMacros 24 | 25 | - (instancetype)init 26 | { 27 | self = [super init]; 28 | if (self == nil) 29 | return nil; 30 | 31 | handler = [UKTestHandler handler]; 32 | handler.delegate = self; 33 | return self; 34 | } 35 | 36 | - (void)reportStatus: (BOOL)cond inFile: (char *)filename line: (int)line message: (NSString *)msg 37 | { 38 | reportedStatus = cond; 39 | } 40 | 41 | /* 42 | // This is a bunch of test failures that I use just to show things failing 43 | - (void) testAllFailures 44 | { 45 | [handler setDelegate:nil]; 46 | UKFail(); 47 | UKTrue(NO); 48 | UKFalse(YES); 49 | UKNil(@"fwip"); 50 | UKNil(self); 51 | UKNotNil(nil); 52 | UKIntsEqual(3, 4); 53 | UKIntsNotEqual(3, 3); 54 | UKFloatsEqual(22.0, 33.0, 1.0); 55 | UKFloatsNotEqual(22.1, 22.2, 0.2); 56 | UKObjectsEqual(self, @"foo"); 57 | UKObjectsNotEqual(self, self); 58 | UKObjectsSame(self, @"foo"); 59 | UKObjectsNotSame(@"foo", @"foo"); 60 | UKStringsEqual(@"fraggle", @"rock"); 61 | UKStringsNotEqual(@"fraggle", @"fraggle"); 62 | UKStringContains(@"fraggle", @"no"); 63 | UKStringDoesNotContain(@"fraggle", @"fra"); 64 | } 65 | */ 66 | 67 | - (void)testUKPass 68 | { 69 | UKPass(); 70 | handler.delegate = nil; 71 | NSAssert(reportedStatus, @"Failsafe check on UKPass"); 72 | UKTrue(reportedStatus); 73 | } 74 | 75 | - (void)testUKPassWithMessage 76 | { 77 | UKPass(); 78 | handler.delegate = nil; 79 | NSAssert(reportedStatus, @"Failsafe check on UKPass"); 80 | } 81 | 82 | - (void)testUKFail 83 | { 84 | UKFail(); 85 | handler.delegate = nil; 86 | NSAssert(!reportedStatus, @"Failsafe check on UKFail"); 87 | UKFalse(reportedStatus); 88 | } 89 | 90 | - (void)testUKTrue_Simple 91 | { 92 | UKTrue(YES); 93 | handler.delegate = nil; 94 | NSAssert(reportedStatus, @"Failsafe check on UKTrue"); 95 | UKTrue(reportedStatus); 96 | } 97 | 98 | - (void)testUKTrue_Simple_Negative 99 | { 100 | UKTrue(NO); 101 | handler.delegate = nil; 102 | NSAssert(!reportedStatus, @"Failsafe check on UKTrue"); 103 | UKFalse(reportedStatus); 104 | } 105 | 106 | - (void)testUKTrue_Conditional_GreaterThan 107 | { 108 | UKTrue(42 > 41); 109 | handler.delegate = nil; 110 | UKTrue(reportedStatus); 111 | } 112 | 113 | - (void)testUKTrue_Conditional_GreaterThan_Negative 114 | { 115 | UKTrue(41 > 42); 116 | handler.delegate = nil; 117 | UKFalse(reportedStatus); 118 | } 119 | 120 | - (void)testUKTrue_Conditional_LessThan 121 | { 122 | UKTrue(41 < 42); 123 | handler.delegate = nil; 124 | UKTrue(reportedStatus); 125 | } 126 | 127 | - (void)testUKTrue_Conditional_LessThan_Negative 128 | { 129 | UKTrue(41 < 40); 130 | handler.delegate = nil; 131 | UKFalse(reportedStatus); 132 | } 133 | 134 | - (void)testUKTrue_Conditional_Equal 135 | { 136 | UKTrue(42 == 42); 137 | handler.delegate = nil; 138 | UKTrue(reportedStatus); 139 | } 140 | 141 | - (void)testUKTrue_Conditional_Equal_Negative 142 | { 143 | UKTrue(42 == 41); 144 | handler.delegate = nil; 145 | UKFalse(reportedStatus); 146 | } 147 | 148 | - (void)testUKTrue_Conditional_NotEqual 149 | { 150 | UKTrue(42 != 41); 151 | handler.delegate = nil; 152 | UKTrue(reportedStatus); 153 | } 154 | 155 | - (void)testUKTrue_Conditional_NotEqual_Negative 156 | { 157 | UKTrue(42 != 42); 158 | handler.delegate = nil; 159 | UKFalse(reportedStatus); 160 | } 161 | 162 | - (void)testUKTrue_Message 163 | { 164 | UKTrue([@"foofart" hasPrefix: @"foo"]); 165 | handler.delegate = nil; 166 | UKTrue(reportedStatus); 167 | } 168 | 169 | - (void)testUKTrue_Message_Negative 170 | { 171 | UKTrue([@"foofart" hasPrefix: @"fart"]); 172 | handler.delegate = nil; 173 | UKFalse(reportedStatus); 174 | } 175 | 176 | - (void)testUKFalse 177 | { 178 | UKFalse(NO); 179 | handler.delegate = nil; 180 | NSAssert(reportedStatus, @"Failsafe check on UKFalse"); 181 | UKTrue(reportedStatus); 182 | } 183 | 184 | - (void)testUKFalse_Negative 185 | { 186 | UKFalse(YES); 187 | handler.delegate = nil; 188 | NSAssert(!reportedStatus, @"Failsafe check on UKFalse"); 189 | UKFalse(reportedStatus); 190 | } 191 | 192 | - (void)testUKFalse_Message 193 | { 194 | UKTrue([@"foofart" hasPrefix: @"fart"]); 195 | handler.delegate = nil; 196 | UKFalse(reportedStatus); 197 | } 198 | 199 | - (void)testUKFalse_Message_Negative 200 | { 201 | UKTrue([@"foofart" hasPrefix: @"foo"]); 202 | handler.delegate = nil; 203 | UKTrue(reportedStatus); 204 | } 205 | 206 | - (void)testUKNil_withNil 207 | { 208 | UKNil(nil); 209 | handler.delegate = nil; 210 | UKTrue(reportedStatus); 211 | } 212 | 213 | - (void)testUKNil_withNull 214 | { 215 | UKNil(NULL); 216 | handler.delegate = nil; 217 | UKTrue(reportedStatus); 218 | } 219 | 220 | - (void)testUKNil_with0 221 | { 222 | // since zero is zero *and* the value of the nil pointer... 223 | UKNil(0); 224 | handler.delegate = nil; 225 | UKTrue(reportedStatus); 226 | } 227 | 228 | - (void)testUKNil_with 229 | { 230 | // XXX 231 | } 232 | 233 | - (void)testUKNil_NegativeWithObject 234 | { 235 | UKNil(@""); 236 | handler.delegate = nil; 237 | UKFalse(reportedStatus); 238 | } 239 | 240 | - (void)testUKNil_NegativeWithPointer 241 | { 242 | // XXX 243 | } 244 | 245 | - (void)testUKNotNil 246 | { 247 | UKNotNil(@""); 248 | handler.delegate = nil; 249 | UKTrue(reportedStatus); 250 | } 251 | 252 | - (void)testUKNotNil_NegativeWithNil 253 | { 254 | UKNotNil(nil); 255 | handler.delegate = nil; 256 | UKFalse(reportedStatus); 257 | } 258 | 259 | - (void)testUKNotNil_NegativeWithNull 260 | { 261 | UKNotNil(NULL); 262 | handler.delegate = nil; 263 | UKFalse(reportedStatus); 264 | } 265 | 266 | - (void)testUKNotNil_NegativeWith0 267 | { 268 | UKNotNil(0); 269 | handler.delegate = nil; 270 | UKFalse(reportedStatus); 271 | } 272 | 273 | - (void)testUKIntsEqual 274 | { 275 | UKIntsEqual(42, 42); 276 | handler.delegate = nil; 277 | UKTrue(reportedStatus); 278 | } 279 | 280 | - (void)testUKIntsEqual_Negative 281 | { 282 | UKIntsEqual(42, 41); 283 | handler.delegate = nil; 284 | UKFalse(reportedStatus); 285 | } 286 | 287 | - (void)testUKFloatsEqual1 288 | { 289 | UKFloatsEqual(42.100, 42.100, 0.01); 290 | handler.delegate = nil; 291 | UKTrue(reportedStatus); 292 | } 293 | 294 | - (void)testUKFloatsEqual2 295 | { 296 | UKFloatsEqual(42.100, 42.200, 0.2); 297 | handler.delegate = nil; 298 | UKTrue(reportedStatus); 299 | } 300 | 301 | - (void)testUKFloatsEqual3 302 | { 303 | UKFloatsEqual(1.0, 1.0, 0.0); 304 | handler.delegate = nil; 305 | UKTrue(reportedStatus); 306 | } 307 | 308 | - (void)testUKFloatsEqual4 309 | { 310 | UKFloatsEqual(1.0, 1.0, 0.01); 311 | handler.delegate = nil; 312 | UKTrue(reportedStatus); 313 | } 314 | 315 | - (void)testUKFloatsEqual_Negative1 316 | { 317 | UKFloatsEqual(42.100, 43.100, 0.01); 318 | handler.delegate = nil; 319 | UKFalse(reportedStatus); 320 | } 321 | 322 | - (void)testUKFloatsEqual_Negative2 323 | { 324 | UKFloatsEqual(42.100, 42.200, 0.08); 325 | handler.delegate = nil; 326 | UKFalse(reportedStatus); 327 | } 328 | 329 | 330 | - (void)testUKFloatsNotEqual 331 | { 332 | UKFloatsNotEqual(42.100, 43.100, 0.01); 333 | handler.delegate = nil; 334 | UKTrue(reportedStatus); 335 | } 336 | 337 | - (void)testUKFloatsEqual_Negative 338 | { 339 | UKFloatsNotEqual(42.1000, 42.1000, 0.01); 340 | handler.delegate = nil; 341 | UKFalse(reportedStatus); 342 | } 343 | 344 | - (void)testUKObjectsEqual1 345 | { 346 | UKObjectsEqual(self, self); 347 | handler.delegate = nil; 348 | UKTrue(reportedStatus); 349 | } 350 | 351 | - (void)testUKObjectsEqual2 352 | { 353 | NSString *string = @""; 354 | UKObjectsEqual(string, [NSString stringWithString: string]); 355 | handler.delegate = nil; 356 | UKTrue(reportedStatus); 357 | } 358 | 359 | - (void)testUKObjectsEqual_Negative 360 | { 361 | UKObjectsEqual(@"", @"123"); 362 | handler.delegate = nil; 363 | UKFalse(reportedStatus); 364 | } 365 | 366 | - (void)testUKStringsEqual1 367 | { 368 | UKStringsEqual(@"abc", @"abc"); 369 | handler.delegate = nil; 370 | UKTrue(reportedStatus); 371 | } 372 | 373 | - (void)testUKStringsEqual2 374 | { 375 | NSString *string = @"abc"; 376 | UKStringsEqual(string, [NSString stringWithString: string]); 377 | handler.delegate = nil; 378 | UKTrue(reportedStatus); 379 | } 380 | 381 | - (void)testUKStringsEqual3 382 | { 383 | NSString *string = [NSString stringWithCString: "abc" 384 | encoding: NSUTF8StringEncoding]; 385 | UKStringsEqual(@"abc", string); 386 | handler.delegate = nil; 387 | UKTrue(reportedStatus); 388 | } 389 | 390 | - (void)testUKStringsEqual_Negative 391 | { 392 | UKStringsEqual(@"abc", @"bea"); 393 | handler.delegate = nil; 394 | UKFalse(reportedStatus); 395 | } 396 | 397 | - (void)testUKStringsNotEqual 398 | { 399 | UKStringsNotEqual(@"abc", @"bea"); 400 | handler.delegate = nil; 401 | UKTrue(reportedStatus); 402 | } 403 | 404 | - (void)testUKStringsNotEqual_Negative1 405 | { 406 | UKStringsNotEqual(@"abc", @"abc"); 407 | handler.delegate = nil; 408 | UKFalse(reportedStatus); 409 | } 410 | 411 | - (void)testUKStringsNotEqual_Negative2 412 | { 413 | NSString *string = @"abc"; 414 | UKStringsNotEqual(string, [NSString stringWithString: string]); 415 | handler.delegate = nil; 416 | UKFalse(reportedStatus); 417 | } 418 | 419 | - (void)testUKStringsNotEqual_Negative3 420 | { 421 | NSString *string = [NSString stringWithCString: "abc" 422 | encoding: NSUTF8StringEncoding]; 423 | UKStringsNotEqual(@"abc", string); 424 | handler.delegate = nil; 425 | UKFalse(reportedStatus); 426 | } 427 | 428 | 429 | - (void)testUKStringContains 430 | { 431 | UKStringContains(@"Now is the time", @"the time"); 432 | handler.delegate = nil; 433 | UKTrue(reportedStatus); 434 | } 435 | 436 | - (void)testUKStringContains_Negative 437 | { 438 | UKStringContains(@"asdf", @"zzzzz"); 439 | handler.delegate = nil; 440 | UKFalse(reportedStatus); 441 | } 442 | 443 | - (void)testUKStringDoesNotContain 444 | { 445 | UKStringDoesNotContain(@"asdf", @"zzzzz"); 446 | handler.delegate = nil; 447 | UKTrue(reportedStatus); 448 | } 449 | 450 | - (void)testUKStringDoesNotContain_Negative 451 | { 452 | UKStringDoesNotContain(@"Now is the time", @"the time"); 453 | handler.delegate = nil; 454 | UKFalse(reportedStatus); 455 | } 456 | 457 | - (void)raiseException: (id)objectToRaise 458 | { 459 | @throw objectToRaise; 460 | } 461 | 462 | - (void)doNotRaiseException 463 | { 464 | // this is fun... do nothing 465 | } 466 | 467 | - (void)testUKRaisesException 468 | { 469 | UKRaisesException([self raiseException: @"Hi"]); 470 | handler.delegate = nil; 471 | UKTrue(reportedStatus); 472 | } 473 | 474 | - (void)testUKRaisesException_Negative 475 | { 476 | UKRaisesException([self doNotRaiseException]); 477 | handler.delegate = nil; 478 | UKFalse(reportedStatus); 479 | } 480 | 481 | - (void)testUKDoesNotRaisesException 482 | { 483 | UKDoesNotRaiseException([self doNotRaiseException]); 484 | handler.delegate = nil; 485 | UKTrue(reportedStatus); 486 | } 487 | 488 | - (void)testUKDoesNotRaisesException_Negative 489 | { 490 | UKDoesNotRaiseException([self raiseException: @"Hi"]); 491 | handler.delegate = nil; 492 | UKFalse(reportedStatus); 493 | } 494 | 495 | - (void)testUKRaisesExceptionNamed 496 | { 497 | NSException *e = [NSException exceptionWithName: @"Test" 498 | reason: @"For testing" 499 | userInfo: nil]; 500 | 501 | UKRaisesExceptionNamed([self raiseException: e], @"Test"); 502 | handler.delegate = nil; 503 | UKTrue(reportedStatus); 504 | } 505 | 506 | - (void)testUKRaisesExceptionNamed_WrongNSException 507 | { 508 | NSException *e = [NSException exceptionWithName: @"Test" 509 | reason: @"For testing" 510 | userInfo: nil]; 511 | 512 | UKRaisesExceptionNamed([self raiseException: e], @"Wrong"); 513 | handler.delegate = nil; 514 | UKFalse(reportedStatus); 515 | } 516 | 517 | - (void)testUKRaisesExceptionNamed_WrongClass 518 | { 519 | UKRaisesExceptionNamed([self raiseException: @"Not an NSException"], @"Wrong"); 520 | handler.delegate = nil; 521 | UKFalse(reportedStatus); 522 | } 523 | 524 | - (void)testUKRaisesExceptionClass 525 | { 526 | UKRaisesExceptionClass([self raiseException: @"aSTring"], NSString); 527 | handler.delegate = nil; 528 | UKTrue(reportedStatus); 529 | } 530 | 531 | - (void)testUKRaisesClass_Wrong 532 | { 533 | UKRaisesExceptionClass([self raiseException: @"aSTring"], NSException); 534 | handler.delegate = nil; 535 | UKFalse(reportedStatus); 536 | } 537 | 538 | 539 | @end 540 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKTestMessages.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | @interface UKTestMessages : NSObject 26 | { 27 | UKTestHandler *handler; 28 | NSString *reportedMessage; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /TestSource/TestUnitKit/UKTestMessages.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import "UKTestMessages.h" 23 | 24 | @implementation UKTestMessages 25 | 26 | - (instancetype)init 27 | { 28 | self = [super init]; 29 | if (self == nil) 30 | return nil; 31 | 32 | handler = [UKTestHandler handler]; 33 | handler.delegate = self; 34 | return self; 35 | } 36 | 37 | - (NSString *)localizedString: (NSString *)key 38 | { 39 | NSBundle *bundle = [NSBundle bundleForClass: [UKTestHandler class]]; 40 | return NSLocalizedStringFromTableInBundle(key, @"UKTestHandler", bundle, @""); 41 | } 42 | 43 | - (void)reportStatus: (BOOL)cond 44 | inFile: (char *)filename 45 | line: (int)line 46 | message: (NSString *)msg 47 | { 48 | reportedMessage = msg; 49 | } 50 | 51 | - (void)testUKPass 52 | { 53 | UKPass(); 54 | handler.delegate = nil; 55 | UKStringsEqual([self localizedString: @"msgUKPass"], reportedMessage); 56 | } 57 | 58 | - (void)testUKFail 59 | { 60 | UKFail(); 61 | handler.delegate = nil; 62 | UKStringsEqual([self localizedString: @"msgUKFail"], reportedMessage); 63 | } 64 | 65 | - (void)testUKTrue 66 | { 67 | UKTrue(YES); 68 | handler.delegate = nil; 69 | UKStringsEqual([self localizedString: @"msgUKTrue.pass"], reportedMessage); 70 | } 71 | 72 | - (void)testUKTrue_Negative 73 | { 74 | UKTrue(NO); 75 | handler.delegate = nil; 76 | UKStringsEqual([self localizedString: @"msgUKTrue.fail"], reportedMessage); 77 | } 78 | 79 | - (void)testUKFalse 80 | { 81 | UKFalse(NO); 82 | handler.delegate = nil; 83 | UKStringsEqual([self localizedString: @"msgUKFalse.pass"], reportedMessage); 84 | } 85 | 86 | - (void)testUKFalse_Negative 87 | { 88 | UKFalse(YES); 89 | handler.delegate = nil; 90 | UKStringsEqual([self localizedString: @"msgUKFalse.fail"], reportedMessage); 91 | } 92 | 93 | - (void)testUKNil 94 | { 95 | UKNil(nil); 96 | handler.delegate = nil; 97 | UKStringsEqual([self localizedString: @"msgUKNil.pass"], reportedMessage); 98 | } 99 | 100 | - (void)testUKNil_Negative 101 | { 102 | UKNil(@""); 103 | handler.delegate = nil; 104 | NSString *expected = [NSString stringWithFormat: 105 | [self localizedString: @"msgUKNil.fail"], @"\"\""]; 106 | UKStringsEqual(expected, reportedMessage); 107 | } 108 | 109 | - (void)testUKNotNil 110 | { 111 | UKNotNil(@""); 112 | handler.delegate = nil; 113 | NSString *expected = [NSString stringWithFormat: 114 | [self localizedString: @"msgUKNotNil.pass"], @"\"\""]; 115 | UKStringsEqual(expected, reportedMessage); 116 | } 117 | 118 | - (void)testUKNotNil_Negative 119 | { 120 | UKNotNil(nil); 121 | handler.delegate = nil; 122 | UKStringsEqual([self localizedString: @"msgUKNotNil.fail"], reportedMessage); 123 | } 124 | 125 | - (void)testUKIntsEqual 126 | { 127 | UKIntsEqual(1, 1); 128 | handler.delegate = nil; 129 | NSString *expected = [NSString stringWithFormat: 130 | [self localizedString: @"msgUKIntsEqual.pass"], 1, 1]; 131 | UKStringsEqual(expected, reportedMessage); 132 | } 133 | 134 | - (void)testUKIntsEqual_Negative 135 | { 136 | UKIntsEqual(1, 2); 137 | handler.delegate = nil; 138 | NSString *expected = [NSString stringWithFormat: 139 | [self localizedString: @"msgUKIntsEqual.fail"], 1, 2]; 140 | UKStringsEqual(expected, reportedMessage); 141 | } 142 | 143 | - (void)testUKFloatsEqual 144 | { 145 | float a = 1.0; 146 | UKFloatsEqual(a, a, 0.1); 147 | NSString *expected = [NSString stringWithFormat: 148 | [self localizedString: @"msgUKFloatsEqual.pass"], a, a]; 149 | UKStringsEqual(expected, reportedMessage); 150 | } 151 | 152 | - (void)testUKFloatsEqual_Negative 153 | { 154 | float a = 1.0; 155 | float b = 2.0; 156 | UKFloatsEqual(a, b, 0.1); 157 | handler.delegate = nil; 158 | NSString *expected = [NSString stringWithFormat: 159 | [self localizedString: @"msgUKFloatsEqual.fail"], a - 0.1, a + 0.1, b]; 160 | UKStringsEqual(expected, reportedMessage); 161 | } 162 | 163 | - (void)testUKFloatsNotEqual 164 | { 165 | float a = 1.0; 166 | float b = 2.0; 167 | UKFloatsNotEqual(a, b, 0.1); 168 | handler.delegate = nil; 169 | NSString *expected = [NSString stringWithFormat: 170 | [self localizedString: @"msgUKFloatsNotEqual.pass"], a - 0.1, a + 0.1, b]; 171 | UKStringsEqual(expected, reportedMessage); 172 | } 173 | 174 | - (void)testUKFloatsNotEqual_Negative 175 | { 176 | float a = 1.0; 177 | float b = 1.0; 178 | UKFloatsNotEqual(a, b, 0.1); 179 | handler.delegate = nil; 180 | NSString *expected = [NSString stringWithFormat: 181 | [self localizedString: @"msgUKFloatsNotEqual.fail"], a - 0.1, a + 0.1, b]; 182 | UKStringsEqual(expected, reportedMessage); 183 | } 184 | 185 | - (void)testUKObjectsEqual 186 | { 187 | UKObjectsEqual(self, self); 188 | handler.delegate = nil; 189 | NSString *objDescription = [NSString stringWithFormat: @"\"%@\"", self]; 190 | NSString *expected = [NSString stringWithFormat: 191 | [self localizedString: @"msgUKObjectsEqual.pass"], objDescription, objDescription]; 192 | UKStringsEqual(expected, reportedMessage); 193 | } 194 | 195 | - (void)testUKObjectsEqual_Negative 196 | { 197 | UKObjectsEqual(self, @"asdf"); 198 | handler.delegate = nil; 199 | NSString *objDescription = [NSString stringWithFormat: @"\"%@\"", self]; 200 | NSString *expected = [NSString stringWithFormat: 201 | [self localizedString: @"msgUKObjectsEqual.fail"], objDescription, @"\"asdf\""]; 202 | UKStringsEqual(expected, reportedMessage); 203 | } 204 | 205 | - (void)testUKObjectsSame 206 | { 207 | UKObjectsSame(self, self); 208 | handler.delegate = nil; 209 | NSString *objDescription = [NSString stringWithFormat: @"\"%@\"", self]; 210 | NSString *expected = [NSString stringWithFormat: 211 | [self localizedString: @"msgUKObjectsSame.pass"], objDescription, objDescription]; 212 | UKStringsEqual(expected, reportedMessage); 213 | } 214 | 215 | - (void)testUKObjectsSame_Negative 216 | { 217 | UKObjectsSame(self, @"asdf"); 218 | handler.delegate = nil; 219 | NSString *objDescription = [NSString stringWithFormat: @"\"%@\"", self]; 220 | NSString *expected = [NSString stringWithFormat: 221 | [self localizedString: @"msgUKObjectsSame.fail"], objDescription, @"\"asdf\""]; 222 | UKStringsEqual(expected, reportedMessage); 223 | } 224 | 225 | - (void)testUKStringsEqual 226 | { 227 | UKStringsEqual(@"a", @"a"); 228 | handler.delegate = nil; 229 | NSString *expected = [NSString stringWithFormat: 230 | [self localizedString: @"msgUKStringsEqual.pass"], @"\"a\"", @"\"a\""]; 231 | UKStringsEqual(expected, reportedMessage); 232 | } 233 | 234 | - (void)testUKStringsEqual_Negative 235 | { 236 | UKStringsEqual(@"a", @"b"); 237 | handler.delegate = nil; 238 | NSString *expected = [NSString stringWithFormat: 239 | [self localizedString: @"msgUKStringsEqual.fail"], @"\"a\"", @"\"b\""]; 240 | UKStringsEqual(expected, reportedMessage); 241 | } 242 | 243 | - (void)testUKStringContains 244 | { 245 | UKStringContains(@"Now is the time", @"the time"); 246 | handler.delegate = nil; 247 | NSString *expected = [NSString stringWithFormat: 248 | [self localizedString: @"msgUKStringContains.pass"], @"\"Now is the time\"", @"\"the time\""]; 249 | UKStringsEqual(expected, reportedMessage); 250 | } 251 | 252 | - (void)testUKStringContains_Negative 253 | { 254 | UKStringContains(@"asdf", @"zzzzz"); 255 | handler.delegate = nil; 256 | NSString *expected = [NSString stringWithFormat: 257 | [self localizedString: @"msgUKStringContains.fail"], @"\"asdf\"", @"\"zzzzz\""]; 258 | UKStringsEqual(expected, reportedMessage); 259 | } 260 | 261 | - (void)testUKStringDoesNotContain 262 | { 263 | UKStringDoesNotContain(@"asdf", @"zzzzz"); 264 | handler.delegate = nil; 265 | NSString *expected = [NSString stringWithFormat: 266 | [self localizedString: @"msgUKStringDoesNotContain.pass"], @"\"asdf\"", @"\"zzzzz\""]; 267 | UKStringsEqual(expected, reportedMessage); 268 | } 269 | 270 | - (void)testUKStringDoesNotContain_Negative 271 | { 272 | UKStringDoesNotContain(@"Now is the time", @"the time"); 273 | handler.delegate = nil; 274 | NSString *expected = [NSString stringWithFormat: 275 | [self localizedString: @"msgUKStringDoesNotContain.fail"], @"\"Now is the time\"", @"\"the time\""]; 276 | UKStringsEqual(expected, reportedMessage); 277 | } 278 | 279 | @end 280 | -------------------------------------------------------------------------------- /ToolSource/GNUmakefile: -------------------------------------------------------------------------------- 1 | include $(GNUSTEP_MAKEFILES)/common.make 2 | 3 | PRINT_PROJECT_NAME = NO 4 | 5 | TOOL_NAME = ukrun 6 | 7 | # For UnitKit, etoile.make after-all:: is not executed before all subprojects 8 | # are built. Hence UnitKit.framework is not present in the Build directory at 9 | # 'ukrun' build time. 10 | ukrun_INCLUDE_DIRS = -I.. 11 | ukrun_LIB_DIRS = -L../UnitKit.framework 12 | ukrun_TOOL_LIBS = -lUnitKit $(FND_LIBS) 13 | 14 | ukrun_OBJC_FILES = main.m 15 | 16 | include ../compilerflags.preamble 17 | 18 | include $(GNUSTEP_MAKEFILES)/tool.make 19 | -include ../../../etoile.make 20 | -------------------------------------------------------------------------------- /ToolSource/main.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2004 James Duncan Davidson 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | int main(int argc, const char *argv[]) 26 | { 27 | int retval; 28 | @autoreleasepool 29 | { 30 | retval = [UKRunner runTests]; 31 | } 32 | return retval; 33 | } 34 | -------------------------------------------------------------------------------- /UnitKit.xcodeproj/xcshareddata/xcschemes/TestUnitKit (iOS).xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /UnitKit.xcodeproj/xcshareddata/xcschemes/TestUnitKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 57 | 58 | 61 | 62 | 63 | 64 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /UnitKit.xcodeproj/xcshareddata/xcschemes/ukrun.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 53 | 59 | 60 | 61 | 62 | 68 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Xcode3Integration/FileTemplates/TemplateInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CounterpartTemplateFile 6 | class.h 7 | Description 8 | An Objective-C class file set up to be detected as a UnitKit test 9 | MainTemplateFile 10 | class.m 11 | 12 | 13 | -------------------------------------------------------------------------------- /Xcode3Integration/FileTemplates/class.h: -------------------------------------------------------------------------------- 1 | // 2 | // «FILENAME» 3 | // «PROJECTNAME» 4 | // 5 | // Created by «FULLUSERNAME» on «DATE». 6 | // Copyright (c) «YEAR» «ORGANIZATIONNAME». All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface «FILEBASENAMEASIDENTIFIER» : NSObject { 13 | 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Xcode3Integration/FileTemplates/class.m: -------------------------------------------------------------------------------- 1 | // 2 | // «FILENAME» 3 | // «PROJECTNAME» 4 | // 5 | // Created by «FULLUSERNAME» on «DATE». 6 | // Copyright (c) «YEAR» «ORGANIZATIONNAME». All rights reserved. 7 | // 8 | 9 | #import "«FILEBASENAME».h" 10 | 11 | 12 | @implementation «FILEBASENAMEASIDENTIFIER» 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Xcode3Integration/TargetTemplates/UnitKitBundle.trgttmpl: -------------------------------------------------------------------------------- 1 | { 2 | Class = Native; 3 | ProductType = "com.apple.product-type.bundle"; 4 | Description = "Target for building a loadable bundle for use by UnitKit."; 5 | CustomBuildSettings = { 6 | INSTALL_PATH = "$(HOME)/Library/Bundles"; 7 | INFOPLIST_FILE = "«PRODUCTNAME»-Info.plist"; 8 | OTHER_LDFLAGS = "-framework Foundation -framework AppKit -framework UnitKit"; 9 | GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; 10 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 11 | WRAPPER_EXTENSION = bundle; 12 | PRODUCT_NAME = "«PRODUCTNAME»"; 13 | }; 14 | CustomProductSettings = { 15 | CFBundleExecutable = "«PRODUCTNAME»"; 16 | CFBundleInfoDictionaryVersion = "6.0"; 17 | CFBundleShortVersionString = "1.0"; 18 | CFBundleVersion = "1"; 19 | CFBundleIdentifier = "com.yourcompany.${PRODUCT_NAME:rfc1034identifier}"; 20 | CFBundleDevelopmentRegion = English; 21 | CFBundlePackageType = "BNDL"; 22 | CFBundleSignature = "????"; 23 | }; 24 | BuildPhases = ( 25 | { 26 | Class = Headers; 27 | }, 28 | { 29 | Class = Resources; 30 | }, 31 | { 32 | Class = Sources; 33 | }, 34 | { 35 | Class = Frameworks; 36 | }, 37 | { 38 | Class = ShellScript; 39 | ShellPath = /bin/bash; 40 | ShellScript = "/usr/local/bin/ukrun \"$TARGET_BUILD_DIR/$PRODUCT_NAME.$WRAPPER_EXTENSION\""; 41 | }, 42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /XcodeIntegration/File Templates/Cocoa/Objective-C UnitKit test case class.xctemplate/NSObject/___FILEBASENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface ___FILEBASENAMEASIDENTIFIER___ : ___VARIABLE_testSubclass___ 13 | 14 | @end 15 | 16 | @implementation ___FILEBASENAMEASIDENTIFIER___ 17 | 18 | + (void) testClass 19 | { 20 | UKFail(); 21 | } 22 | 23 | - (void) testInstance 24 | { 25 | UKPass(); 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /XcodeIntegration/File Templates/Cocoa/Objective-C UnitKit test case class.xctemplate/TemplateIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etoile/UnitKit/fd2bd2a9f05db78c50a8a6b49a39f97b8b095881/XcodeIntegration/File Templates/Cocoa/Objective-C UnitKit test case class.xctemplate/TemplateIcon.icns -------------------------------------------------------------------------------- /XcodeIntegration/File Templates/Cocoa/Objective-C UnitKit test case class.xctemplate/TemplateInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AllowedTypes 6 | 7 | public.objective-c-source 8 | public.objective-c-plus-plus-source 9 | 10 | BuildableType 11 | Test 12 | DefaultCompletionName 13 | Test 14 | Description 15 | An Objective-C class implementing a unit test (using the UnitKit framework). 16 | Kind 17 | Xcode.IDEKit.TextSubstitutionFileTemplateKind 18 | MainTemplateFile 19 | ___FILEBASENAME___.m 20 | Options 21 | 22 | 23 | Description 24 | Name of the unit test class to create 25 | Identifier 26 | productName 27 | Name 28 | Class 29 | NotPersisted 30 | Yes 31 | Required 32 | Yes 33 | Type 34 | text 35 | 36 | 37 | Default 38 | NSObject 39 | Description 40 | Unit test class that the new class will be a subclass of 41 | Identifier 42 | testSubclass 43 | Name 44 | Subclass of 45 | Required 46 | Yes 47 | Type 48 | class 49 | Values 50 | 51 | 52 | 53 | Platforms 54 | 55 | com.apple.platform.macosx 56 | 57 | Summary 58 | An Objective-C class implementing a unit test 59 | 60 | 61 | -------------------------------------------------------------------------------- /XcodeIntegration/Project Templates/Mac/Other/UnitKit Testing Bundle.xctemplate/TemplateIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etoile/UnitKit/fd2bd2a9f05db78c50a8a6b49a39f97b8b095881/XcodeIntegration/Project Templates/Mac/Other/UnitKit Testing Bundle.xctemplate/TemplateIcon.icns -------------------------------------------------------------------------------- /XcodeIntegration/Project Templates/Mac/Other/UnitKit Testing Bundle.xctemplate/TemplateInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IsUnitTest 6 | 7 | Kind 8 | Xcode.Xcode3.ProjectTemplateUnitKind 9 | Identifier 10 | com.apple.dt.unit.UnitKitTestBundle 11 | Concrete 12 | 13 | Description 14 | This template builds a bundle that links against the UnitKit test framework. 15 | SortOrder 16 | 3 17 | Ancestors 18 | 19 | com.apple.dt.unit.bundleBase 20 | com.apple.dt.unit.macBase 21 | 22 | Targets 23 | 24 | 25 | ProductType 26 | com.apple.product-type.bundle 27 | SharedSettings 28 | 29 | WRAPPER_EXTENSION 30 | bundle 31 | COMBINE_HIDPI_IMAGES 32 | YES 33 | 34 | BuildPhases 35 | 36 | 37 | Class 38 | ShellScript 39 | ShellPath 40 | /bin/bash 41 | ShellScript 42 | export DYLD_FRAMEWORK_PATH=$LIBRARY_SEARCH_PATHS:$TARGET_BUILD_DIR;ukrun "$TARGET_BUILD_DIR/$PRODUCT_NAME.$WRAPPER_EXTENSION" 43 | 44 | 45 | Class 46 | Sources 47 | 48 | 49 | Class 50 | Frameworks 51 | 52 | 53 | Class 54 | Resources 55 | 56 | 57 | 58 | 59 | Options 60 | 61 | 62 | Identifier 63 | bundleFramework 64 | Name 65 | Framework 66 | Description 67 | Which framework the bundle should link against 68 | Type 69 | popup 70 | Default 71 | UnitKit 72 | Units 73 | 74 | UnitKit 75 | 76 | 77 | Targets 78 | 79 | 80 | Frameworks 81 | 82 | UnitKit 83 | Foundation 84 | 85 | OtherFrameworks 86 | 87 | 88 | 89 | Nodes 90 | 91 | ___PACKAGENAME___-Info.plist:bundleCocoa 92 | 93 | Definitions 94 | 95 | ___PACKAGENAME___-Info.plist:bundleCocoa 96 | <key>NSPrincipalClass</key> 97 | <string></string> 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | Nodes 106 | 107 | ___PACKAGENAME___-Prefix.pch:objC:importCocoa 108 | ___PACKAGENAME___-Info.plist:bundle 109 | ___PACKAGENAME___-Info.plist:NSHumanReadableCopyright 110 | 111 | Definitions 112 | 113 | ___PACKAGENAME___-Info.plist:bundle 114 | <key>CFBundleDevelopmentRegion</key> 115 | <string>English</string> 116 | <key>CFBundleExecutable</key> 117 | <string>${EXECUTABLE_NAME}</string> 118 | <key>CFBundleName</key> 119 | <string>${PRODUCT_NAME}</string> 120 | <key>CFBundleIconFile</key> 121 | <string></string> 122 | <key>CFBundleInfoDictionaryVersion</key> 123 | <string>6.0</string> 124 | <key>CFBundlePackageType</key> 125 | <string>BNDL</string> 126 | <key>CFBundleSignature</key> 127 | <string>????</string> 128 | <key>CFBundleVersion</key> 129 | <string>1</string> 130 | <key>CFBundleShortVersionString</key> 131 | <string>1.0</string> 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /compilerflags.preamble: -------------------------------------------------------------------------------- 1 | ADDITIONAL_OBJCFLAGS = -std=c99 -fobjc-arc 2 | -------------------------------------------------------------------------------- /iOSCompatibility/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/etoile/UnitKit/fd2bd2a9f05db78c50a8a6b49a39f97b8b095881/iOSCompatibility/Default-568h@2x.png -------------------------------------------------------------------------------- /iOSCompatibility/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | ${CURRENT_MARKETING_VERSION} 21 | CFBundleSignature 22 | ???? 23 | LSRequiresIPhoneOS 24 | 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /iOSCompatibility/main.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Quentin Mathe 3 | 4 | License: Apache License, Version 2.0 (see LICENSE) 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | The use of the Apache License does not indicate that this project is 19 | affiliated with the Apache Software Foundation. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | int main(int argc, char *argv[]) 26 | { 27 | int status = EXIT_FAILURE; 28 | 29 | @autoreleasepool 30 | { 31 | UKRunner *runner = [UKRunner new]; 32 | 33 | [[UKTestHandler handler] setQuiet: YES]; 34 | 35 | [runner runTestsInBundle: [NSBundle mainBundle]]; 36 | status = [runner reportTestResults]; 37 | } 38 | 39 | return status; 40 | } 41 | -------------------------------------------------------------------------------- /test-linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o verbose 4 | 5 | export CC=clang-3.8 6 | export CXX=clang++-3.8 7 | 8 | LIBOBJC2_VERSION=1.8.1 9 | MAKE_VERSION=2.6.7 10 | BASE_VERSION=1.24.9 11 | 12 | # deps 13 | sudo apt-get -y install libblocksruntime-dev libkqueue-dev libpthread-workqueue-dev cmake 14 | sudo apt-get -y install libxml2-dev libxslt1-dev libffi-dev libssl-dev libgnutls-dev libicu-dev libgmp3-dev 15 | sudo apt-get -y install libjpeg-dev libtiff-dev libpng-dev libgif-dev libx11-dev libcairo2-dev libxft-dev libxmu-dev 16 | sudo apt-get -y install libsqlite3-dev 17 | 18 | # repos 19 | git clone https://github.com/nickhutchinson/libdispatch 20 | git clone https://github.com/gnustep/libobjc2 21 | # 2.6.8 breaks --disable-mixedabi by omitting -fobjc-nonfragile-abi among the compiler flags 22 | wget -N ftp://ftp.gnustep.org/pub/gnustep/core/gnustep-make-${MAKE_VERSION}.tar.gz && tar -xf gnustep-make-${MAKE_VERSION}.tar.gz 23 | wget -N ftp://ftp.gnustep.org/pub/gnustep/core/gnustep-base-${BASE_VERSION}.tar.gz && tar -xf gnustep-base-${BASE_VERSION}.tar.gz 24 | 25 | # libdispatch 26 | cd libdispatch && git clean -dfx && git checkout bd1808980b04830cbbd79c959b8bc554085e38a1 27 | mkdir build && cd build 28 | ../configure && make && sudo make install || exit 1 29 | cd ../.. 30 | 31 | # libobjc2 32 | cd libobjc2 && git clean -dfx && git checkout tags/v${LIBOBJC2_VERSION} 33 | mkdir build && cd build 34 | # Skip LLVM package check to work around hardcoded paths in LLVM-Config.cmake 35 | cmake .. -DCMAKE_DISABLE_FIND_PACKAGE_LLVM=TRUE && make -j8 && sudo make install || exit 1 36 | cd ../.. 37 | 38 | # gnustep make 39 | cd gnustep-make-${MAKE_VERSION} 40 | ./configure --enable-debug-by-default --enable-objc-nonfragile-abi --enable-objc-arc && make && sudo make install || exit 1 41 | cd .. 42 | source /usr/local/share/GNUstep/Makefiles/GNUstep.sh || exit 1 43 | 44 | # gnustep base 45 | cd gnustep-base-${BASE_VERSION} 46 | ./configure --disable-mixedabi && make -j8 && sudo make install || exit 1 47 | cd .. 48 | 49 | # UnitKit 50 | git clean -dfx 51 | wget https://raw.githubusercontent.com/etoile/Etoile/master/etoile.make 52 | make -j8 messages=yes && sudo make install || exit 1 53 | make -j8 messages=yes test=yes && ukrun -q TestSource/TestUnitKit/TestUnitKit.bundle || exit 1 54 | -------------------------------------------------------------------------------- /test-macosx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # install ukrun first 4 | sudo xcodebuild -target ukrun -configuration Release clean install 5 | 6 | # This is used in the "Run Script" phase of each of the targets we build, 7 | # if it is set to 1, the resulting binary is run as part of the xcodebuild 8 | export TEST_AUTORUN=1 9 | 10 | xcodebuild -project UnitKit.xcodeproj -scheme TestUnitKit 11 | teststatus=$? 12 | 13 | # printstatus 'message' status 14 | function printstatus { 15 | if [[ $2 == 0 ]]; then 16 | echo "(PASS) $1" 17 | else 18 | echo "(FAIL) $1" 19 | fi 20 | } 21 | 22 | echo "UnitKit Tests Summary" 23 | echo "=====================" 24 | printstatus UnitKit $teststatus 25 | 26 | exitstatus=$(( teststatus )) 27 | exit $exitstatus 28 | --------------------------------------------------------------------------------