├── Examples ├── RSTestingKitExamples-Info.plist ├── RSTestingKitExamples.xcodeproj │ ├── project.pbxproj │ └── project.pbxproj.orig ├── RSTestingKitExamples_Prefix.pch ├── TestInputs │ └── TestImage.png ├── Tests_ExampleHTTP.h ├── Tests_ExampleHTTP.m ├── Tests_ExampleHTTP.m.orig ├── Tests_ExampleInput.h ├── Tests_ExampleInput.m ├── Tests_ExampleRunLoop.h ├── Tests_ExampleRunLoop.m └── Tests_ExampleRunLoop.m.orig ├── Framework ├── English.lproj │ └── InfoPlist.strings ├── RSHTTPClientTestCase │ ├── GTMDebugSelectorValidation.h │ ├── GTMDefines.h │ ├── GTMGarbageCollection.h │ ├── GTMHTTPServer.h │ ├── GTMHTTPServer.m │ ├── RSHTTPClientTestCase.h │ └── RSHTTPClientTestCase.m ├── RSRunLoopWaitingTestCase.h ├── RSRunLoopWaitingTestCase.m ├── RSTestCase.h ├── RSTestCase.m ├── RSTestingKit-Info.plist ├── RSTestingKit.h ├── RSTestingKit.xcodeproj │ └── project.pbxproj └── RSTestingKit_Prefix.pch ├── License.txt └── readme.md /Examples/RSTestingKitExamples-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.yourcompany.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Examples/RSTestingKitExamples.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6532000F127E43E300227DF8 /* Tests_ExampleInput.m in Sources */ = {isa = PBXBuildFile; fileRef = 6532000E127E43E300227DF8 /* Tests_ExampleInput.m */; }; 11 | 65320032127E49B100227DF8 /* TestInputs in Resources */ = {isa = PBXBuildFile; fileRef = 6532002F127E49B100227DF8 /* TestInputs */; }; 12 | 65320041127E4A5C00227DF8 /* Tests_ExampleRunLoop.m in Sources */ = {isa = PBXBuildFile; fileRef = 65320040127E4A5C00227DF8 /* Tests_ExampleRunLoop.m */; }; 13 | 6532FE97127DF98300227DF8 /* Tests_ExampleHTTP.m in Sources */ = {isa = PBXBuildFile; fileRef = 6532FE96127DF98300227DF8 /* Tests_ExampleHTTP.m */; }; 14 | 6532FFEC127E38CD00227DF8 /* RSTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6532FFE9127E38B400227DF8 /* RSTestingKit.framework */; }; 15 | 65EDFC781280997E0039F5C2 /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 65EDFC771280997E0039F5C2 /* License.txt */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXContainerItemProxy section */ 19 | 6532FFE8127E38B400227DF8 /* PBXContainerItemProxy */ = { 20 | isa = PBXContainerItemProxy; 21 | containerPortal = 6532FFE4127E38B400227DF8 /* RSTestingKit.xcodeproj */; 22 | proxyType = 2; 23 | remoteGlobalIDString = 8DC2EF5B0486A6940098B216; 24 | remoteInfo = RSTestingKit; 25 | }; 26 | 6532FFEA127E38BB00227DF8 /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 6532FFE4127E38B400227DF8 /* RSTestingKit.xcodeproj */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 8DC2EF4F0486A6940098B216; 31 | remoteInfo = RSTestingKit; 32 | }; 33 | /* End PBXContainerItemProxy section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 37 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 38 | 32DBCF5E0370ADEE00C91783 /* RSTestingKitExamples_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSTestingKitExamples_Prefix.pch; sourceTree = ""; }; 39 | 6532000D127E43E300227DF8 /* Tests_ExampleInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tests_ExampleInput.h; sourceTree = ""; }; 40 | 6532000E127E43E300227DF8 /* Tests_ExampleInput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Tests_ExampleInput.m; sourceTree = ""; }; 41 | 6532002F127E49B100227DF8 /* TestInputs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = TestInputs; sourceTree = ""; }; 42 | 6532003F127E4A5C00227DF8 /* Tests_ExampleRunLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tests_ExampleRunLoop.h; sourceTree = ""; }; 43 | 65320040127E4A5C00227DF8 /* Tests_ExampleRunLoop.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Tests_ExampleRunLoop.m; sourceTree = ""; }; 44 | 6532FE7C127DF89E00227DF8 /* RSTestingKitExamples.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RSTestingKitExamples.octest; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 6532FE7D127DF89E00227DF8 /* RSTestingKitExamples-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RSTestingKitExamples-Info.plist"; sourceTree = ""; }; 46 | 6532FE95127DF98300227DF8 /* Tests_ExampleHTTP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tests_ExampleHTTP.h; sourceTree = ""; }; 47 | 6532FE96127DF98300227DF8 /* Tests_ExampleHTTP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Tests_ExampleHTTP.m; sourceTree = ""; }; 48 | 6532FFE4127E38B400227DF8 /* RSTestingKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSTestingKit.xcodeproj; path = ../Framework/RSTestingKit.xcodeproj; sourceTree = SOURCE_ROOT; }; 49 | 65EDFC771280997E0039F5C2 /* License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = License.txt; path = ../License.txt; sourceTree = SOURCE_ROOT; }; 50 | 8DC2EF5A0486A6940098B216 /* RSTestingKitExamples-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "RSTestingKitExamples-Info.plist"; sourceTree = ""; }; 51 | /* End PBXFileReference section */ 52 | 53 | /* Begin PBXFrameworksBuildPhase section */ 54 | 6532FE79127DF89E00227DF8 /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | 6532FFEC127E38CD00227DF8 /* RSTestingKit.framework in Frameworks */, 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | 034768DFFF38A50411DB9C8B /* Products */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 6532FE7C127DF89E00227DF8 /* RSTestingKitExamples.octest */, 69 | ); 70 | name = Products; 71 | sourceTree = ""; 72 | }; 73 | 0867D691FE84028FC02AAC07 /* RSTestingKitExamples */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 65EDFC771280997E0039F5C2 /* License.txt */, 77 | 32DBCF5E0370ADEE00C91783 /* RSTestingKitExamples_Prefix.pch */, 78 | 6532000D127E43E300227DF8 /* Tests_ExampleInput.h */, 79 | 6532000E127E43E300227DF8 /* Tests_ExampleInput.m */, 80 | 6532003F127E4A5C00227DF8 /* Tests_ExampleRunLoop.h */, 81 | 65320040127E4A5C00227DF8 /* Tests_ExampleRunLoop.m */, 82 | 6532FE95127DF98300227DF8 /* Tests_ExampleHTTP.h */, 83 | 6532FE96127DF98300227DF8 /* Tests_ExampleHTTP.m */, 84 | 089C1665FE841158C02AAC07 /* Resources */, 85 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 86 | 034768DFFF38A50411DB9C8B /* Products */, 87 | 6532FE7D127DF89E00227DF8 /* RSTestingKitExamples-Info.plist */, 88 | ); 89 | name = RSTestingKitExamples; 90 | sourceTree = ""; 91 | }; 92 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 6532FFE4127E38B400227DF8 /* RSTestingKit.xcodeproj */, 96 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, 97 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 98 | ); 99 | name = "External Frameworks and Libraries"; 100 | sourceTree = ""; 101 | }; 102 | 089C1665FE841158C02AAC07 /* Resources */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 6532002F127E49B100227DF8 /* TestInputs */, 106 | 8DC2EF5A0486A6940098B216 /* RSTestingKitExamples-Info.plist */, 107 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */, 108 | ); 109 | name = Resources; 110 | sourceTree = ""; 111 | }; 112 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | ); 116 | name = "Linked Frameworks"; 117 | sourceTree = ""; 118 | }; 119 | 6532FFE5127E38B400227DF8 /* Products */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 6532FFE9127E38B400227DF8 /* RSTestingKit.framework */, 123 | ); 124 | name = Products; 125 | sourceTree = ""; 126 | }; 127 | /* End PBXGroup section */ 128 | 129 | /* Begin PBXNativeTarget section */ 130 | 6532FE7B127DF89E00227DF8 /* RSTestingKitExamples */ = { 131 | isa = PBXNativeTarget; 132 | buildConfigurationList = 6532FE80127DF89F00227DF8 /* Build configuration list for PBXNativeTarget "RSTestingKitExamples" */; 133 | buildPhases = ( 134 | 6532FE77127DF89E00227DF8 /* Resources */, 135 | 6532FE78127DF89E00227DF8 /* Sources */, 136 | 6532FE79127DF89E00227DF8 /* Frameworks */, 137 | 6532FE7A127DF89E00227DF8 /* ShellScript */, 138 | ); 139 | buildRules = ( 140 | ); 141 | dependencies = ( 142 | 6532FFEB127E38BB00227DF8 /* PBXTargetDependency */, 143 | ); 144 | name = RSTestingKitExamples; 145 | productName = RSTestingKitExamples; 146 | productReference = 6532FE7C127DF89E00227DF8 /* RSTestingKitExamples.octest */; 147 | productType = "com.apple.product-type.bundle"; 148 | }; 149 | /* End PBXNativeTarget section */ 150 | 151 | /* Begin PBXProject section */ 152 | 0867D690FE84028FC02AAC07 /* Project object */ = { 153 | isa = PBXProject; 154 | buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "RSTestingKitExamples" */; 155 | compatibilityVersion = "Xcode 3.1"; 156 | developmentRegion = English; 157 | hasScannedForEncodings = 1; 158 | knownRegions = ( 159 | English, 160 | Japanese, 161 | French, 162 | German, 163 | ); 164 | mainGroup = 0867D691FE84028FC02AAC07 /* RSTestingKitExamples */; 165 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 166 | projectDirPath = ""; 167 | projectReferences = ( 168 | { 169 | ProductGroup = 6532FFE5127E38B400227DF8 /* Products */; 170 | ProjectRef = 6532FFE4127E38B400227DF8 /* RSTestingKit.xcodeproj */; 171 | }, 172 | ); 173 | projectRoot = ""; 174 | targets = ( 175 | 6532FE7B127DF89E00227DF8 /* RSTestingKitExamples */, 176 | ); 177 | }; 178 | /* End PBXProject section */ 179 | 180 | /* Begin PBXReferenceProxy section */ 181 | 6532FFE9127E38B400227DF8 /* RSTestingKit.framework */ = { 182 | isa = PBXReferenceProxy; 183 | fileType = wrapper.framework; 184 | path = RSTestingKit.framework; 185 | remoteRef = 6532FFE8127E38B400227DF8 /* PBXContainerItemProxy */; 186 | sourceTree = BUILT_PRODUCTS_DIR; 187 | }; 188 | /* End PBXReferenceProxy section */ 189 | 190 | /* Begin PBXResourcesBuildPhase section */ 191 | 6532FE77127DF89E00227DF8 /* Resources */ = { 192 | isa = PBXResourcesBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | 65320032127E49B100227DF8 /* TestInputs in Resources */, 196 | 65EDFC781280997E0039F5C2 /* License.txt in Resources */, 197 | ); 198 | runOnlyForDeploymentPostprocessing = 0; 199 | }; 200 | /* End PBXResourcesBuildPhase section */ 201 | 202 | /* Begin PBXShellScriptBuildPhase section */ 203 | 6532FE7A127DF89E00227DF8 /* ShellScript */ = { 204 | isa = PBXShellScriptBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | ); 208 | inputPaths = ( 209 | ); 210 | outputPaths = ( 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | shellPath = /bin/sh; 214 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; 215 | }; 216 | /* End PBXShellScriptBuildPhase section */ 217 | 218 | /* Begin PBXSourcesBuildPhase section */ 219 | 6532FE78127DF89E00227DF8 /* Sources */ = { 220 | isa = PBXSourcesBuildPhase; 221 | buildActionMask = 2147483647; 222 | files = ( 223 | 6532FE97127DF98300227DF8 /* Tests_ExampleHTTP.m in Sources */, 224 | 6532000F127E43E300227DF8 /* Tests_ExampleInput.m in Sources */, 225 | 65320041127E4A5C00227DF8 /* Tests_ExampleRunLoop.m in Sources */, 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | }; 229 | /* End PBXSourcesBuildPhase section */ 230 | 231 | /* Begin PBXTargetDependency section */ 232 | 6532FFEB127E38BB00227DF8 /* PBXTargetDependency */ = { 233 | isa = PBXTargetDependency; 234 | name = RSTestingKit; 235 | targetProxy = 6532FFEA127E38BB00227DF8 /* PBXContainerItemProxy */; 236 | }; 237 | /* End PBXTargetDependency section */ 238 | 239 | /* Begin PBXVariantGroup section */ 240 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { 241 | isa = PBXVariantGroup; 242 | children = ( 243 | 089C1667FE841158C02AAC07 /* English */, 244 | ); 245 | name = InfoPlist.strings; 246 | sourceTree = ""; 247 | }; 248 | /* End PBXVariantGroup section */ 249 | 250 | /* Begin XCBuildConfiguration section */ 251 | 1DEB91B208733DA50010E9CD /* Debug */ = { 252 | isa = XCBuildConfiguration; 253 | buildSettings = { 254 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 255 | GCC_C_LANGUAGE_STANDARD = gnu99; 256 | GCC_OPTIMIZATION_LEVEL = 0; 257 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 258 | GCC_WARN_UNUSED_VARIABLE = YES; 259 | ONLY_ACTIVE_ARCH = YES; 260 | PREBINDING = NO; 261 | SDKROOT = macosx10.6; 262 | }; 263 | name = Debug; 264 | }; 265 | 1DEB91B308733DA50010E9CD /* Release */ = { 266 | isa = XCBuildConfiguration; 267 | buildSettings = { 268 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 269 | GCC_C_LANGUAGE_STANDARD = gnu99; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 271 | GCC_WARN_UNUSED_VARIABLE = YES; 272 | PREBINDING = NO; 273 | SDKROOT = macosx10.6; 274 | }; 275 | name = Release; 276 | }; 277 | 6532FE7E127DF89F00227DF8 /* Debug */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | ALWAYS_SEARCH_USER_PATHS = NO; 281 | COPY_PHASE_STRIP = NO; 282 | FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks"; 283 | GCC_DYNAMIC_NO_PIC = NO; 284 | GCC_ENABLE_FIX_AND_CONTINUE = NO; 285 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 286 | GCC_MODEL_TUNING = G5; 287 | GCC_OPTIMIZATION_LEVEL = 0; 288 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 289 | GCC_PREFIX_HEADER = RSTestingKitExamples_Prefix.pch; 290 | INFOPLIST_FILE = "RSTestingKitExamples-Info.plist"; 291 | INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles"; 292 | OTHER_LDFLAGS = ( 293 | "-framework", 294 | Cocoa, 295 | "-framework", 296 | SenTestingKit, 297 | ); 298 | PREBINDING = NO; 299 | PRODUCT_NAME = RSTestingKitExamples; 300 | WRAPPER_EXTENSION = octest; 301 | }; 302 | name = Debug; 303 | }; 304 | 6532FE7F127DF89F00227DF8 /* Release */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | ALWAYS_SEARCH_USER_PATHS = NO; 308 | COPY_PHASE_STRIP = YES; 309 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 310 | FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks"; 311 | GCC_ENABLE_FIX_AND_CONTINUE = NO; 312 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 313 | GCC_MODEL_TUNING = G5; 314 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 315 | GCC_PREFIX_HEADER = RSTestingKitExamples_Prefix.pch; 316 | INFOPLIST_FILE = "RSTestingKitExamples-Info.plist"; 317 | INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles"; 318 | OTHER_LDFLAGS = ( 319 | "-framework", 320 | Cocoa, 321 | "-framework", 322 | SenTestingKit, 323 | ); 324 | PREBINDING = NO; 325 | PRODUCT_NAME = RSTestingKitExamples; 326 | WRAPPER_EXTENSION = octest; 327 | ZERO_LINK = NO; 328 | }; 329 | name = Release; 330 | }; 331 | /* End XCBuildConfiguration section */ 332 | 333 | /* Begin XCConfigurationList section */ 334 | 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "RSTestingKitExamples" */ = { 335 | isa = XCConfigurationList; 336 | buildConfigurations = ( 337 | 1DEB91B208733DA50010E9CD /* Debug */, 338 | 1DEB91B308733DA50010E9CD /* Release */, 339 | ); 340 | defaultConfigurationIsVisible = 0; 341 | defaultConfigurationName = Release; 342 | }; 343 | 6532FE80127DF89F00227DF8 /* Build configuration list for PBXNativeTarget "RSTestingKitExamples" */ = { 344 | isa = XCConfigurationList; 345 | buildConfigurations = ( 346 | 6532FE7E127DF89F00227DF8 /* Debug */, 347 | 6532FE7F127DF89F00227DF8 /* Release */, 348 | ); 349 | defaultConfigurationIsVisible = 0; 350 | defaultConfigurationName = Release; 351 | }; 352 | /* End XCConfigurationList section */ 353 | }; 354 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 355 | } 356 | -------------------------------------------------------------------------------- /Examples/RSTestingKitExamples.xcodeproj/project.pbxproj.orig: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6532000F127E43E300227DF8 /* Tests_ExampleInput.m in Sources */ = {isa = PBXBuildFile; fileRef = 6532000E127E43E300227DF8 /* Tests_ExampleInput.m */; }; 11 | 65320032127E49B100227DF8 /* TestInputs in Resources */ = {isa = PBXBuildFile; fileRef = 6532002F127E49B100227DF8 /* TestInputs */; }; 12 | 65320041127E4A5C00227DF8 /* Tests_ExampleRunLoop.m in Sources */ = {isa = PBXBuildFile; fileRef = 65320040127E4A5C00227DF8 /* Tests_ExampleRunLoop.m */; }; 13 | 6532FE97127DF98300227DF8 /* Tests_ExampleHTTP.m in Sources */ = {isa = PBXBuildFile; fileRef = 6532FE96127DF98300227DF8 /* Tests_ExampleHTTP.m */; }; 14 | 6532FFEC127E38CD00227DF8 /* RSTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6532FFE9127E38B400227DF8 /* RSTestingKit.framework */; }; 15 | 65EDFC62128097E40039F5C2 /* untitled.m in Sources */ = {isa = PBXBuildFile; fileRef = 65EDFC61128097E40039F5C2 /* untitled.m */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXContainerItemProxy section */ 19 | 6532FFE8127E38B400227DF8 /* PBXContainerItemProxy */ = { 20 | isa = PBXContainerItemProxy; 21 | containerPortal = 6532FFE4127E38B400227DF8 /* RSTestingKit.xcodeproj */; 22 | proxyType = 2; 23 | remoteGlobalIDString = 8DC2EF5B0486A6940098B216; 24 | remoteInfo = RSTestingKit; 25 | }; 26 | 6532FFEA127E38BB00227DF8 /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 6532FFE4127E38B400227DF8 /* RSTestingKit.xcodeproj */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 8DC2EF4F0486A6940098B216; 31 | remoteInfo = RSTestingKit; 32 | }; 33 | /* End PBXContainerItemProxy section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 37 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 38 | 32DBCF5E0370ADEE00C91783 /* RSTestingKitExamples_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSTestingKitExamples_Prefix.pch; sourceTree = ""; }; 39 | 6532000D127E43E300227DF8 /* Tests_ExampleInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tests_ExampleInput.h; sourceTree = ""; }; 40 | 6532000E127E43E300227DF8 /* Tests_ExampleInput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Tests_ExampleInput.m; sourceTree = ""; }; 41 | 6532002F127E49B100227DF8 /* TestInputs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = TestInputs; sourceTree = ""; }; 42 | 6532003F127E4A5C00227DF8 /* Tests_ExampleRunLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tests_ExampleRunLoop.h; sourceTree = ""; }; 43 | 65320040127E4A5C00227DF8 /* Tests_ExampleRunLoop.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Tests_ExampleRunLoop.m; sourceTree = ""; }; 44 | 6532FE7C127DF89E00227DF8 /* RSTestingKitExamples.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RSTestingKitExamples.octest; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 6532FE7D127DF89E00227DF8 /* RSTestingKitExamples-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RSTestingKitExamples-Info.plist"; sourceTree = ""; }; 46 | 6532FE95127DF98300227DF8 /* Tests_ExampleHTTP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tests_ExampleHTTP.h; sourceTree = ""; }; 47 | 6532FE96127DF98300227DF8 /* Tests_ExampleHTTP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Tests_ExampleHTTP.m; sourceTree = ""; }; 48 | 6532FFE4127E38B400227DF8 /* RSTestingKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSTestingKit.xcodeproj; path = ../Framework/RSTestingKit.xcodeproj; sourceTree = SOURCE_ROOT; }; 49 | 65EDFC5D128094AB0039F5C2 /* License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = License.txt; path = ../License.txt; sourceTree = SOURCE_ROOT; }; 50 | 65EDFC60128097E40039F5C2 /* untitled.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = untitled.h; sourceTree = ""; }; 51 | 65EDFC61128097E40039F5C2 /* untitled.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = untitled.m; sourceTree = ""; }; 52 | 8DC2EF5A0486A6940098B216 /* RSTestingKitExamples-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "RSTestingKitExamples-Info.plist"; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 6532FE79127DF89E00227DF8 /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | 6532FFEC127E38CD00227DF8 /* RSTestingKit.framework in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 034768DFFF38A50411DB9C8B /* Products */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 6532FE7C127DF89E00227DF8 /* RSTestingKitExamples.octest */, 71 | ); 72 | name = Products; 73 | sourceTree = ""; 74 | }; 75 | 0867D691FE84028FC02AAC07 /* RSTestingKitExamples */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 65EDFC60128097E40039F5C2 /* untitled.h */, 79 | 65EDFC61128097E40039F5C2 /* untitled.m */, 80 | 65EDFC5D128094AB0039F5C2 /* License.txt */, 81 | 32DBCF5E0370ADEE00C91783 /* RSTestingKitExamples_Prefix.pch */, 82 | 6532000D127E43E300227DF8 /* Tests_ExampleInput.h */, 83 | 6532000E127E43E300227DF8 /* Tests_ExampleInput.m */, 84 | 6532003F127E4A5C00227DF8 /* Tests_ExampleRunLoop.h */, 85 | 65320040127E4A5C00227DF8 /* Tests_ExampleRunLoop.m */, 86 | 6532FE95127DF98300227DF8 /* Tests_ExampleHTTP.h */, 87 | 6532FE96127DF98300227DF8 /* Tests_ExampleHTTP.m */, 88 | 089C1665FE841158C02AAC07 /* Resources */, 89 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 90 | 034768DFFF38A50411DB9C8B /* Products */, 91 | 6532FE7D127DF89E00227DF8 /* RSTestingKitExamples-Info.plist */, 92 | ); 93 | name = RSTestingKitExamples; 94 | sourceTree = ""; 95 | }; 96 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 6532FFE4127E38B400227DF8 /* RSTestingKit.xcodeproj */, 100 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, 101 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 102 | ); 103 | name = "External Frameworks and Libraries"; 104 | sourceTree = ""; 105 | }; 106 | 089C1665FE841158C02AAC07 /* Resources */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 6532002F127E49B100227DF8 /* TestInputs */, 110 | 8DC2EF5A0486A6940098B216 /* RSTestingKitExamples-Info.plist */, 111 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */, 112 | ); 113 | name = Resources; 114 | sourceTree = ""; 115 | }; 116 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | ); 120 | name = "Linked Frameworks"; 121 | sourceTree = ""; 122 | }; 123 | 6532FFE5127E38B400227DF8 /* Products */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 6532FFE9127E38B400227DF8 /* RSTestingKit.framework */, 127 | ); 128 | name = Products; 129 | sourceTree = ""; 130 | }; 131 | /* End PBXGroup section */ 132 | 133 | /* Begin PBXNativeTarget section */ 134 | 6532FE7B127DF89E00227DF8 /* RSTestingKitExamples */ = { 135 | isa = PBXNativeTarget; 136 | buildConfigurationList = 6532FE80127DF89F00227DF8 /* Build configuration list for PBXNativeTarget "RSTestingKitExamples" */; 137 | buildPhases = ( 138 | 6532FE77127DF89E00227DF8 /* Resources */, 139 | 6532FE78127DF89E00227DF8 /* Sources */, 140 | 6532FE79127DF89E00227DF8 /* Frameworks */, 141 | 6532FE7A127DF89E00227DF8 /* ShellScript */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | 6532FFEB127E38BB00227DF8 /* PBXTargetDependency */, 147 | ); 148 | name = RSTestingKitExamples; 149 | productName = RSTestingKitExamples; 150 | productReference = 6532FE7C127DF89E00227DF8 /* RSTestingKitExamples.octest */; 151 | productType = "com.apple.product-type.bundle"; 152 | }; 153 | /* End PBXNativeTarget section */ 154 | 155 | /* Begin PBXProject section */ 156 | 0867D690FE84028FC02AAC07 /* Project object */ = { 157 | isa = PBXProject; 158 | buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "RSTestingKitExamples" */; 159 | compatibilityVersion = "Xcode 3.1"; 160 | developmentRegion = English; 161 | hasScannedForEncodings = 1; 162 | knownRegions = ( 163 | English, 164 | Japanese, 165 | French, 166 | German, 167 | ); 168 | mainGroup = 0867D691FE84028FC02AAC07 /* RSTestingKitExamples */; 169 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 170 | projectDirPath = ""; 171 | projectReferences = ( 172 | { 173 | ProductGroup = 6532FFE5127E38B400227DF8 /* Products */; 174 | ProjectRef = 6532FFE4127E38B400227DF8 /* RSTestingKit.xcodeproj */; 175 | }, 176 | ); 177 | projectRoot = ""; 178 | targets = ( 179 | 6532FE7B127DF89E00227DF8 /* RSTestingKitExamples */, 180 | ); 181 | }; 182 | /* End PBXProject section */ 183 | 184 | /* Begin PBXReferenceProxy section */ 185 | 6532FFE9127E38B400227DF8 /* RSTestingKit.framework */ = { 186 | isa = PBXReferenceProxy; 187 | fileType = wrapper.framework; 188 | path = RSTestingKit.framework; 189 | remoteRef = 6532FFE8127E38B400227DF8 /* PBXContainerItemProxy */; 190 | sourceTree = BUILT_PRODUCTS_DIR; 191 | }; 192 | /* End PBXReferenceProxy section */ 193 | 194 | /* Begin PBXResourcesBuildPhase section */ 195 | 6532FE77127DF89E00227DF8 /* Resources */ = { 196 | isa = PBXResourcesBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | 65320032127E49B100227DF8 /* TestInputs in Resources */, 200 | ); 201 | runOnlyForDeploymentPostprocessing = 0; 202 | }; 203 | /* End PBXResourcesBuildPhase section */ 204 | 205 | /* Begin PBXShellScriptBuildPhase section */ 206 | 6532FE7A127DF89E00227DF8 /* ShellScript */ = { 207 | isa = PBXShellScriptBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | ); 211 | inputPaths = ( 212 | ); 213 | outputPaths = ( 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | shellPath = /bin/sh; 217 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; 218 | }; 219 | /* End PBXShellScriptBuildPhase section */ 220 | 221 | /* Begin PBXSourcesBuildPhase section */ 222 | 6532FE78127DF89E00227DF8 /* Sources */ = { 223 | isa = PBXSourcesBuildPhase; 224 | buildActionMask = 2147483647; 225 | files = ( 226 | 6532FE97127DF98300227DF8 /* Tests_ExampleHTTP.m in Sources */, 227 | 6532000F127E43E300227DF8 /* Tests_ExampleInput.m in Sources */, 228 | 65320041127E4A5C00227DF8 /* Tests_ExampleRunLoop.m in Sources */, 229 | 65EDFC62128097E40039F5C2 /* untitled.m in Sources */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXSourcesBuildPhase section */ 234 | 235 | /* Begin PBXTargetDependency section */ 236 | 6532FFEB127E38BB00227DF8 /* PBXTargetDependency */ = { 237 | isa = PBXTargetDependency; 238 | name = RSTestingKit; 239 | targetProxy = 6532FFEA127E38BB00227DF8 /* PBXContainerItemProxy */; 240 | }; 241 | /* End PBXTargetDependency section */ 242 | 243 | /* Begin PBXVariantGroup section */ 244 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { 245 | isa = PBXVariantGroup; 246 | children = ( 247 | 089C1667FE841158C02AAC07 /* English */, 248 | ); 249 | name = InfoPlist.strings; 250 | sourceTree = ""; 251 | }; 252 | /* End PBXVariantGroup section */ 253 | 254 | /* Begin XCBuildConfiguration section */ 255 | 1DEB91B208733DA50010E9CD /* Debug */ = { 256 | isa = XCBuildConfiguration; 257 | buildSettings = { 258 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 259 | GCC_C_LANGUAGE_STANDARD = gnu99; 260 | GCC_OPTIMIZATION_LEVEL = 0; 261 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 262 | GCC_WARN_UNUSED_VARIABLE = YES; 263 | ONLY_ACTIVE_ARCH = YES; 264 | PREBINDING = NO; 265 | SDKROOT = macosx10.6; 266 | }; 267 | name = Debug; 268 | }; 269 | 1DEB91B308733DA50010E9CD /* Release */ = { 270 | isa = XCBuildConfiguration; 271 | buildSettings = { 272 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 273 | GCC_C_LANGUAGE_STANDARD = gnu99; 274 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 275 | GCC_WARN_UNUSED_VARIABLE = YES; 276 | PREBINDING = NO; 277 | SDKROOT = macosx10.6; 278 | }; 279 | name = Release; 280 | }; 281 | 6532FE7E127DF89F00227DF8 /* Debug */ = { 282 | isa = XCBuildConfiguration; 283 | buildSettings = { 284 | ALWAYS_SEARCH_USER_PATHS = NO; 285 | COPY_PHASE_STRIP = NO; 286 | FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks"; 287 | GCC_DYNAMIC_NO_PIC = NO; 288 | GCC_ENABLE_FIX_AND_CONTINUE = NO; 289 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 290 | GCC_MODEL_TUNING = G5; 291 | GCC_OPTIMIZATION_LEVEL = 0; 292 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 293 | GCC_PREFIX_HEADER = RSTestingKitExamples_Prefix.pch; 294 | INFOPLIST_FILE = "RSTestingKitExamples-Info.plist"; 295 | INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles"; 296 | OTHER_LDFLAGS = ( 297 | "-framework", 298 | Cocoa, 299 | "-framework", 300 | SenTestingKit, 301 | ); 302 | PREBINDING = NO; 303 | PRODUCT_NAME = RSTestingKitExamples; 304 | WRAPPER_EXTENSION = octest; 305 | }; 306 | name = Debug; 307 | }; 308 | 6532FE7F127DF89F00227DF8 /* Release */ = { 309 | isa = XCBuildConfiguration; 310 | buildSettings = { 311 | ALWAYS_SEARCH_USER_PATHS = NO; 312 | COPY_PHASE_STRIP = YES; 313 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 314 | FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks"; 315 | GCC_ENABLE_FIX_AND_CONTINUE = NO; 316 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 317 | GCC_MODEL_TUNING = G5; 318 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 319 | GCC_PREFIX_HEADER = RSTestingKitExamples_Prefix.pch; 320 | INFOPLIST_FILE = "RSTestingKitExamples-Info.plist"; 321 | INSTALL_PATH = "$(USER_LIBRARY_DIR)/Bundles"; 322 | OTHER_LDFLAGS = ( 323 | "-framework", 324 | Cocoa, 325 | "-framework", 326 | SenTestingKit, 327 | ); 328 | PREBINDING = NO; 329 | PRODUCT_NAME = RSTestingKitExamples; 330 | WRAPPER_EXTENSION = octest; 331 | ZERO_LINK = NO; 332 | }; 333 | name = Release; 334 | }; 335 | /* End XCBuildConfiguration section */ 336 | 337 | /* Begin XCConfigurationList section */ 338 | 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "RSTestingKitExamples" */ = { 339 | isa = XCConfigurationList; 340 | buildConfigurations = ( 341 | 1DEB91B208733DA50010E9CD /* Debug */, 342 | 1DEB91B308733DA50010E9CD /* Release */, 343 | ); 344 | defaultConfigurationIsVisible = 0; 345 | defaultConfigurationName = Release; 346 | }; 347 | 6532FE80127DF89F00227DF8 /* Build configuration list for PBXNativeTarget "RSTestingKitExamples" */ = { 348 | isa = XCConfigurationList; 349 | buildConfigurations = ( 350 | 6532FE7E127DF89F00227DF8 /* Debug */, 351 | 6532FE7F127DF89F00227DF8 /* Release */, 352 | ); 353 | defaultConfigurationIsVisible = 0; 354 | defaultConfigurationName = Release; 355 | }; 356 | /* End XCConfigurationList section */ 357 | }; 358 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 359 | } 360 | -------------------------------------------------------------------------------- /Examples/RSTestingKitExamples_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'RSTestingKitExamples' target in the 'RSTestingKitExamples' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /Examples/TestInputs/TestImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielpunkass/RSTestingKit/3194bcdedc5ba0f74a0405f00688a02b11ab26b1/Examples/TestInputs/TestImage.png -------------------------------------------------------------------------------- /Examples/Tests_ExampleHTTP.h: -------------------------------------------------------------------------------- 1 | // 2 | // Tests_ExampleHTTP.h 3 | // RSTestingKitExamples 4 | // 5 | // Created by daniel on 10/31/10. 6 | // Copyright 2010 Red Sweater Software. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface Tests_ExampleHTTP : RSHTTPClientTestCase 13 | { 14 | NSMutableData* mCurrentRequestResponseData; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Examples/Tests_ExampleHTTP.m: -------------------------------------------------------------------------------- 1 | // 2 | // Tests_ExampleHTTP.m 3 | // RSTestingKitExamples 4 | // 5 | // Created by daniel on 10/31/10. 6 | // Copyright 2010 Red Sweater Software. All rights reserved. 7 | // 8 | 9 | #import "Tests_ExampleHTTP.h" 10 | 11 | @interface Tests_ExampleHTTP (Private) 12 | - (NSData*) fetchDataFromURL:(NSURL*)theURL; 13 | @end 14 | 15 | @implementation Tests_ExampleHTTP 16 | 17 | - (void) testSimpleHTTPRequest 18 | { 19 | // In real life, you would be testing some of your code that in turn relies 20 | // on a particular network response. Here, we just pretend that we care deeply about 21 | // the ability of NSURLConnection/Request to successful transfer 22 | // the text string "" through the network stack. 23 | 24 | // The name used for constructing this URL must match the implementation of the "response" method below. 25 | NSURL* simpleHTTPRequestURL = [self serverURLForHTTPTestNamed:@"SimpleHTTPRequest"]; 26 | NSData* responseData = [self fetchDataFromURL:simpleHTTPRequestURL]; 27 | 28 | // We should have gotten the response generated below 29 | NSData* expectedResponseData = [@"" dataUsingEncoding:NSUTF8StringEncoding]; 30 | STAssertTrue([responseData isEqualTo:expectedResponseData], @"Expected result, got %@.", responseData); 31 | } 32 | 33 | - (GTMHTTPResponseMessage *) responseForTestRequest_SimpleHTTPRequest:(GTMHTTPRequestMessage *)request 34 | { 35 | return [GTMHTTPResponseMessage responseWithHTMLString:@""]; 36 | } 37 | 38 | // NSURLConnection delegate stuff 39 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection 40 | { 41 | // Indicate that the test is completed, so the run loop can return control 42 | // to the test that initiated the load 43 | [self setWaitingForTestCompletion:NO]; 44 | } 45 | 46 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 47 | { 48 | [mCurrentRequestResponseData appendData:data]; 49 | } 50 | 51 | - (NSData*) fetchDataFromURL:(NSURL*)theURL 52 | { 53 | [mCurrentRequestResponseData release]; 54 | mCurrentRequestResponseData = [[NSMutableData data] retain]; 55 | 56 | NSURLRequest* theURLRequest = [NSURLRequest requestWithURL:theURL]; 57 | STAssertNotNil(theURLRequest, @"Creation of the HTTP Request should have succeeded."); 58 | 59 | NSURLConnection* theURLConnection = [NSURLConnection connectionWithRequest:theURLRequest delegate:self]; 60 | [theURLConnection retain]; 61 | 62 | // Wait for the network transaction to finish 63 | [self waitForRunLoopTestCompletion]; 64 | 65 | [theURLConnection release]; 66 | 67 | // Return a the data autoreleased, and nil out the instance variable for the next fetch 68 | NSData* returnedData = mCurrentRequestResponseData; 69 | mCurrentRequestResponseData = nil; 70 | return [returnedData autorelease]; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Examples/Tests_ExampleHTTP.m.orig: -------------------------------------------------------------------------------- 1 | // 2 | // Tests_ExampleHTTP.m 3 | // RSTestingKitExamples 4 | // 5 | // Created by daniel on 10/31/10. 6 | // Copyright 2010 Red Sweater Software. All rights reserved. 7 | // 8 | 9 | #import "Tests_ExampleHTTP.h" 10 | 11 | @interface Tests_ExampleHTTP (Private) 12 | - (NSData*) fetchDataFromURL:(NSURL*)theURL; 13 | @end 14 | 15 | @implementation Tests_ExampleHTTP 16 | 17 | 18 | - (void) testSimpleHTTPRequest 19 | { 20 | // In real life, you would be testing some of your code that in turn relies 21 | // on a particular network response. Here, we just pretend that we care deeply about 22 | // the ability of NSURLConnection/Request to successful transfer 23 | // the text string "" through the network stack. 24 | 25 | // The name used for constructing this URL must match the implementation of the "response" method below. 26 | NSURL* simpleHTTPRequestURL = [self serverURLForHTTPTestNamed:@"SimpleHTTPRequest"]; 27 | NSData* responseData = [self fetchDataFromURL:simpleHTTPRequestURL]; 28 | 29 | // We should have gotten the response generated below 30 | NSData* expectedResponseData = [@"" dataUsingEncoding:NSUTF8StringEncoding]; 31 | STAssertTrue([responseData isEqualTo:expectedResponseData], @"Expected result, got %@.", responseData); 32 | } 33 | 34 | - (GTMHTTPResponseMessage *) responseForTestRequest_SimpleHTTPRequest:(GTMHTTPRequestMessage *)request 35 | { 36 | return [GTMHTTPResponseMessage responseWithHTMLString:@""]; 37 | } 38 | 39 | // NSURLConnection delegate stuff 40 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection 41 | { 42 | // Indicate that the test is completed, so the run loop can return control 43 | // to the test that initiated the load 44 | [self setWaitingForTestCompletion:NO]; 45 | } 46 | 47 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 48 | { 49 | [mCurrentRequestResponseData appendData:data]; 50 | } 51 | 52 | - (NSData*) fetchDataFromURL:(NSURL*)theURL 53 | { 54 | [mCurrentRequestResponseData release]; 55 | mCurrentRequestResponseData = [[NSMutableData data] retain]; 56 | 57 | NSURLRequest* theURLRequest = [NSURLRequest requestWithURL:theURL]; 58 | STAssertNotNil(theURLRequest, @"Creation of the HTTP Request should have succeeded."); 59 | 60 | NSURLConnection* theURLConnection = [NSURLConnection connectionWithRequest:theURLRequest delegate:self]; 61 | [theURLConnection retain]; 62 | 63 | // Wait for the network transaction to finish 64 | [self spinRunLoopUntilCompletionOrTimeout]; 65 | 66 | [theURLConnection release]; 67 | 68 | // Return a the data autoreleased, and nil out the instance variable for the next fetch 69 | NSData* returnedData = mCurrentRequestResponseData; 70 | mCurrentRequestResponseData = nil; 71 | return [returnedData autorelease]; 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Examples/Tests_ExampleInput.h: -------------------------------------------------------------------------------- 1 | // 2 | // Tests_ExampleInput.h 3 | // RSTestingKitExamples 4 | // 5 | // Created by daniel on 10/31/10. 6 | // Copyright 2010 Red Sweater Software. All rights reserved. 7 | // 8 | 9 | // THIS Example shows how to use the easy "input resources" feature of RSTestCase to 10 | // load and test against complicated input data. 11 | 12 | #import 13 | #import 14 | 15 | @interface Tests_ExampleInput : RSTestCase 16 | { 17 | 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Examples/Tests_ExampleInput.m: -------------------------------------------------------------------------------- 1 | // 2 | // Tests_ExampleInput.m 3 | // RSTestingKitExamples 4 | // 5 | // Created by daniel on 10/31/10. 6 | // Copyright 2010 Red Sweater Software. All rights reserved. 7 | // 8 | 9 | #import "Tests_ExampleInput.h" 10 | 11 | @implementation Tests_ExampleInput 12 | 13 | - (void) testSimpleInput 14 | { 15 | // Normally you would use the input facility of RSTestCase to e.g. 16 | // provide some complicated data like an XML file or an image to code 17 | // that you are trying to test. IN this example we'll just test the 18 | // ability of NSImage to load an image and return the expected image 19 | // dimensions. 20 | 21 | NSData* imageData = [self dataFromTestInputFilename:@"TestImage.png"]; 22 | 23 | // We don't particularly need to test that imageData != nil, because 24 | // dataFromTestInputFilename will itself raise a test failure if the file is not there. 25 | 26 | // Create the image, check for non-nil-ness, then check for the expected dimensions 27 | NSImage* testImage = [[NSImage alloc] initWithData:imageData]; 28 | STAssertNotNil(testImage, @"Test image input should have produced a good image object."); 29 | 30 | NSString* thisImageSizeString = NSStringFromSize([testImage size]); 31 | NSString* expectedImageSizeString = @"{550, 550}"; 32 | STAssertEqualObjects(thisImageSizeString, expectedImageSizeString, @"Expected %@ size, got %@", expectedImageSizeString, thisImageSizeString); 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Examples/Tests_ExampleRunLoop.h: -------------------------------------------------------------------------------- 1 | // 2 | // Tests_ExampleRunLoop.h 3 | // RSTestingKitExamples 4 | // 5 | // Created by daniel on 10/31/10. 6 | // Copyright 2010 Red Sweater Software. All rights reserved. 7 | // 8 | 9 | // THIS example shows how you might use RSRunLoopWaitingTestCase to exercise 10 | // code that must wait for a runloop-scheduled operation to finish. 11 | 12 | #import 13 | #import 14 | 15 | @interface Tests_ExampleRunLoop : RSRunLoopWaitingTestCase { 16 | 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Examples/Tests_ExampleRunLoop.m: -------------------------------------------------------------------------------- 1 | // 2 | // Tests_ExampleRunLoop.m 3 | // RSTestingKitExamples 4 | // 5 | // Created by daniel on 10/31/10. 6 | // Copyright 2010 Red Sweater Software. All rights reserved. 7 | // 8 | 9 | #import "Tests_ExampleRunLoop.h" 10 | 11 | 12 | @implementation Tests_ExampleRunLoop 13 | 14 | - (void) myDelayedMethod 15 | { 16 | // When we get called, we let the RSRunLoopWaitingTestCase infrastructure know we're done 17 | [self setWaitingForTestCompletion:NO]; 18 | } 19 | 20 | - (void) testSimpleRunLoop 21 | { 22 | // Contrived example, let's make sure that performSelector:withObject:afterDelay: 23 | // doesn't return any earlier than the we ask it to. 24 | 25 | NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate]; 26 | 27 | NSTimeInterval expectedElapsedTime = 1.0; 28 | [self performSelector:@selector(myDelayedMethod) withObject:nil afterDelay:expectedElapsedTime]; 29 | 30 | [self waitForRunLoopTestCompletion]; 31 | 32 | NSTimeInterval endTime = [[NSDate date] timeIntervalSinceReferenceDate]; 33 | NSTimeInterval elapsedTime = (endTime - startTime); 34 | 35 | STAssertEqualsWithAccuracy(elapsedTime, expectedElapsedTime, 0.01, 36 | @"Expected elapsed time around %f, got %f", expectedElapsedTime, elapsedTime); 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Examples/Tests_ExampleRunLoop.m.orig: -------------------------------------------------------------------------------- 1 | // 2 | // Tests_ExampleRunLoop.m 3 | // RSTestingKitExamples 4 | // 5 | // Created by daniel on 10/31/10. 6 | // Copyright 2010 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | @interface NSString (Test) 10 | - (NSString*) stringByReversing; 11 | @end 12 | 13 | #import "Tests_ExampleRunLoop.h" 14 | 15 | 16 | @implementation Tests_ExampleRunLoop 17 | 18 | - (void) myDelayedMethod 19 | { 20 | [self setWaitingForTestCompletion:NO]; 21 | } 22 | 23 | - (void) testSimpleRunLoop 24 | { 25 | // Contrived example, let's make sure that performSelector:withObject:afterDelay: 26 | // doesn't return any earlier than the we ask it to. 27 | 28 | NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate]; 29 | 30 | NSTimeInterval expectedElapsedTime = 1.0; 31 | [self performSelector:@selector(myDelayedMethod) withObject:nil afterDelay:expectedElapsedTime]; 32 | 33 | [self spinRunLoopUntilCompletionOrTimeout]; 34 | 35 | NSTimeInterval endTime = [[NSDate date] timeIntervalSinceReferenceDate]; 36 | NSTimeInterval elapsedTime = (endTime - startTime); 37 | 38 | STAssertEqualsWithAccuracy(elapsedTime, expectedElapsedTime, 0.01, 39 | @"Expected elapsed time around %f, got %f", expectedElapsedTime, elapsedTime); 40 | } 41 | 42 | - (void) testStringReversal 43 | { 44 | NSString* helloString = @"Hello."; 45 | NSString* expectedString = @".olleH"; 46 | 47 | // Reverse the string 48 | NSString* actualString = [helloString stringByReversing]; 49 | 50 | // Confirm expectation 51 | STAssertEqualObjects(expectedString, actualString, 52 | @"Oh crap, we’re screwed."); 53 | } 54 | 55 | @end 56 | 57 | @implementation NSString (Test) 58 | 59 | - (NSString*) stringByReversing 60 | { 61 | return @"o.lleH"; 62 | } 63 | 64 | @end -------------------------------------------------------------------------------- /Framework/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Framework/RSHTTPClientTestCase/GTMDebugSelectorValidation.h: -------------------------------------------------------------------------------- 1 | // 2 | // GTMDebugSelectorValidation.h 3 | // 4 | // This file should only be included within an implimation file. In any 5 | // function that takes an object and selector to invoke, you should call: 6 | // 7 | // GTMAssertSelectorNilOrImplementedWithArguments(obj, sel, @encode(arg1type), ..., NULL) 8 | // or 9 | // GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(obj, sel, @encode(returnType), @encode(arg1type), ..., NULL) 10 | // 11 | // This will then validate that the selector is defined and using the right 12 | // type(s), this can help catch errors much earlier then waiting for the 13 | // selector to actually fire (and in the case of error selectors, might never 14 | // really be tested until in the field). 15 | // 16 | // Copyright 2007-2008 Google Inc. 17 | // 18 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 19 | // use this file except in compliance with the License. You may obtain a copy 20 | // of the License at 21 | // 22 | // http://www.apache.org/licenses/LICENSE-2.0 23 | // 24 | // Unless required by applicable law or agreed to in writing, software 25 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 26 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 27 | // License for the specific language governing permissions and limitations under 28 | // the License. 29 | // 30 | 31 | #if DEBUG 32 | 33 | #import 34 | #import "GTMDefines.h" 35 | 36 | static void GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(id obj, SEL sel, const char *retType, ...) { 37 | 38 | // verify that the object's selector is implemented with the proper 39 | // number and type of arguments 40 | va_list argList; 41 | va_start(argList, retType); 42 | 43 | if (obj && sel) { 44 | // check that the selector is implemented 45 | _GTMDevAssert([obj respondsToSelector:sel], 46 | @"\"%@\" selector \"%@\" is unimplemented or misnamed", 47 | NSStringFromClass([obj class]), 48 | NSStringFromSelector(sel)); 49 | 50 | const char *expectedArgType; 51 | NSUInteger argCount = 2; // skip self and _cmd 52 | NSMethodSignature *sig = [obj methodSignatureForSelector:sel]; 53 | 54 | // check that each expected argument is present and of the correct type 55 | while ((expectedArgType = va_arg(argList, const char*)) != 0) { 56 | 57 | if ([sig numberOfArguments] > argCount) { 58 | const char *foundArgType = [sig getArgumentTypeAtIndex:argCount]; 59 | 60 | _GTMDevAssert(0 == strncmp(foundArgType, expectedArgType, strlen(expectedArgType)), 61 | @"\"%@\" selector \"%@\" argument %d should be type %s", 62 | NSStringFromClass([obj class]), 63 | NSStringFromSelector(sel), 64 | (argCount - 2), 65 | expectedArgType); 66 | } 67 | argCount++; 68 | } 69 | 70 | // check that the proper number of arguments are present in the selector 71 | _GTMDevAssert(argCount == [sig numberOfArguments], 72 | @"\"%@\" selector \"%@\" should have %d arguments", 73 | NSStringFromClass([obj class]), 74 | NSStringFromSelector(sel), 75 | (argCount - 2)); 76 | 77 | // if asked, validate the return type 78 | if (retType && (strcmp("gtm_skip_return_test", retType) != 0)) { 79 | const char *foundRetType = [sig methodReturnType]; 80 | _GTMDevAssert(0 == strncmp(foundRetType, retType, strlen(retType)), 81 | @"\"%@\" selector \"%@\" return type should be type %s", 82 | NSStringFromClass([obj class]), 83 | NSStringFromSelector(sel), 84 | retType); 85 | } 86 | } 87 | 88 | va_end(argList); 89 | } 90 | 91 | #define GTMAssertSelectorNilOrImplementedWithArguments(obj, sel, ...) \ 92 | GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments((obj), (sel), "gtm_skip_return_test", __VA_ARGS__) 93 | 94 | #else // DEBUG 95 | 96 | // make it go away if not debug 97 | #define GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(obj, sel, retType, ...) do { } while (0) 98 | #define GTMAssertSelectorNilOrImplementedWithArguments(obj, sel, ...) do { } while (0) 99 | 100 | #endif // DEBUG 101 | -------------------------------------------------------------------------------- /Framework/RSHTTPClientTestCase/GTMDefines.h: -------------------------------------------------------------------------------- 1 | // 2 | // GTMDefines.h 3 | // 4 | // Copyright 2008 Google Inc. 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 7 | // use this file except in compliance with the License. You may obtain a copy 8 | // 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, WITHOUT 14 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | // License for the specific language governing permissions and limitations under 16 | // the License. 17 | // 18 | 19 | // ============================================================================ 20 | 21 | #include 22 | #include 23 | 24 | // Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs 25 | #ifndef MAC_OS_X_VERSION_10_5 26 | #define MAC_OS_X_VERSION_10_5 1050 27 | #endif 28 | #ifndef MAC_OS_X_VERSION_10_6 29 | #define MAC_OS_X_VERSION_10_6 1060 30 | #endif 31 | 32 | // These definitions exist to allow headerdoc to parse this file. 33 | // Headerdoc 8.6 gives warnings about misuses of MAC_OS_X_VERSION_MIN_REQUIRED 34 | // and MAC_OS_X_VERSION_MAX_ALLOWED if you use them directly. 35 | // By defining GTM versions with slightly different names (MIN vs MINIMUM) 36 | // we get around headerdoc's issues. Hopefully we can work around this in the 37 | // future and get rid of the GTM versions, so please use the default ones 38 | // wherever you can. 39 | #ifndef GTM_MAC_OS_X_VERSION_MINIMUM_REQUIRED 40 | #define GTM_MAC_OS_X_VERSION_MINIMUM_REQUIRED MAC_OS_X_VERSION_MIN_REQUIRED 41 | #endif 42 | 43 | #ifndef GTM_MAC_OS_X_VERSION_MAXIMUM_ALLOWED 44 | #define GTM_MAC_OS_X_VERSION_MAXIMUM_ALLOWED MAC_OS_X_VERSION_MAX_ALLOWED 45 | #endif 46 | 47 | // ---------------------------------------------------------------------------- 48 | // CPP symbols that can be overridden in a prefix to control how the toolbox 49 | // is compiled. 50 | // ---------------------------------------------------------------------------- 51 | 52 | 53 | // By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and 54 | // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens 55 | // when a validation fails. If you implement your own validators, you may want 56 | // to control their internals using the same macros for consistency. 57 | #ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 58 | #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0 59 | #endif 60 | 61 | // Give ourselves a consistent way to do inlines. Apple's macros even use 62 | // a few different actual definitions, so we're based off of the foundation 63 | // one. 64 | #if !defined(GTM_INLINE) 65 | #if defined (__GNUC__) && (__GNUC__ == 4) 66 | #define GTM_INLINE static __inline__ __attribute__((always_inline)) 67 | #else 68 | #define GTM_INLINE static __inline__ 69 | #endif 70 | #endif 71 | 72 | // Give ourselves a consistent way of doing externs that links up nicely 73 | // when mixing objc and objc++ 74 | #if !defined (GTM_EXTERN) 75 | #if defined __cplusplus 76 | #define GTM_EXTERN extern "C" 77 | #else 78 | #define GTM_EXTERN extern 79 | #endif 80 | #endif 81 | 82 | // Give ourselves a consistent way of exporting things if we have visibility 83 | // set to hidden. 84 | #if !defined (GTM_EXPORT) 85 | #define GTM_EXPORT __attribute__((visibility("default"))) 86 | #endif 87 | 88 | // _GTMDevLog & _GTMDevAssert 89 | // 90 | // _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for 91 | // developer level errors. This implementation simply macros to NSLog/NSAssert. 92 | // It is not intended to be a general logging/reporting system. 93 | // 94 | // Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert 95 | // for a little more background on the usage of these macros. 96 | // 97 | // _GTMDevLog log some error/problem in debug builds 98 | // _GTMDevAssert assert if conditon isn't met w/in a method/function 99 | // in all builds. 100 | // 101 | // To replace this system, just provide different macro definitions in your 102 | // prefix header. Remember, any implementation you provide *must* be thread 103 | // safe since this could be called by anything in what ever situtation it has 104 | // been placed in. 105 | // 106 | 107 | // We only define the simple macros if nothing else has defined this. 108 | #ifndef _GTMDevLog 109 | 110 | #ifdef DEBUG 111 | #define _GTMDevLog(...) NSLog(__VA_ARGS__) 112 | #else 113 | #define _GTMDevLog(...) do { } while (0) 114 | #endif 115 | 116 | #endif // _GTMDevLog 117 | 118 | // Declared here so that it can easily be used for logging tracking if 119 | // necessary. See GTMUnitTestDevLog.h for details. 120 | @class NSString; 121 | GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...); 122 | 123 | #ifndef _GTMDevAssert 124 | // we directly invoke the NSAssert handler so we can pass on the varargs 125 | // (NSAssert doesn't have a macro we can use that takes varargs) 126 | #if !defined(NS_BLOCK_ASSERTIONS) 127 | #define _GTMDevAssert(condition, ...) \ 128 | do { \ 129 | if (!(condition)) { \ 130 | [[NSAssertionHandler currentHandler] \ 131 | handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \ 132 | file:[NSString stringWithUTF8String:__FILE__] \ 133 | lineNumber:__LINE__ \ 134 | description:__VA_ARGS__]; \ 135 | } \ 136 | } while(0) 137 | #else // !defined(NS_BLOCK_ASSERTIONS) 138 | #define _GTMDevAssert(condition, ...) do { } while (0) 139 | #endif // !defined(NS_BLOCK_ASSERTIONS) 140 | 141 | #endif // _GTMDevAssert 142 | 143 | // _GTMCompileAssert 144 | // _GTMCompileAssert is an assert that is meant to fire at compile time if you 145 | // want to check things at compile instead of runtime. For example if you 146 | // want to check that a wchar is 4 bytes instead of 2 you would use 147 | // _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X) 148 | // Note that the second "arg" is not in quotes, and must be a valid processor 149 | // symbol in it's own right (no spaces, punctuation etc). 150 | 151 | // Wrapping this in an #ifndef allows external groups to define their own 152 | // compile time assert scheme. 153 | #ifndef _GTMCompileAssert 154 | // We got this technique from here: 155 | // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html 156 | 157 | #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg 158 | #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg) 159 | #define _GTMCompileAssert(test, msg) \ 160 | typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ] 161 | #endif // _GTMCompileAssert 162 | 163 | // Macro to allow fast enumeration when building for 10.5 or later, and 164 | // reliance on NSEnumerator for 10.4. Remember, NSDictionary w/ FastEnumeration 165 | // does keys, so pick the right thing, nothing is done on the FastEnumeration 166 | // side to be sure you're getting what you wanted. 167 | #ifndef GTM_FOREACH_OBJECT 168 | #if TARGET_OS_IPHONE || (GTM_MAC_OS_X_VERSION_MINIMUM_REQUIRED >= MAC_OS_X_VERSION_10_5) 169 | #define GTM_FOREACH_ENUMEREE(element, enumeration) \ 170 | for (element in enumeration) 171 | #define GTM_FOREACH_OBJECT(element, collection) \ 172 | for (element in collection) 173 | #define GTM_FOREACH_KEY(element, collection) \ 174 | for (element in collection) 175 | #else 176 | #define GTM_FOREACH_ENUMEREE(element, enumeration) \ 177 | for (NSEnumerator *_ ## element ## _enum = enumeration; \ 178 | (element = [_ ## element ## _enum nextObject]) != nil; ) 179 | #define GTM_FOREACH_OBJECT(element, collection) \ 180 | GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator]) 181 | #define GTM_FOREACH_KEY(element, collection) \ 182 | GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator]) 183 | #endif 184 | #endif 185 | 186 | // ============================================================================ 187 | 188 | // ---------------------------------------------------------------------------- 189 | // CPP symbols defined based on the project settings so the GTM code has 190 | // simple things to test against w/o scattering the knowledge of project 191 | // setting through all the code. 192 | // ---------------------------------------------------------------------------- 193 | 194 | // Provide a single constant CPP symbol that all of GTM uses for ifdefing 195 | // iPhone code. 196 | #if TARGET_OS_IPHONE // iPhone SDK 197 | // For iPhone specific stuff 198 | #define GTM_IPHONE_SDK 1 199 | #if TARGET_IPHONE_SIMULATOR 200 | #define GTM_IPHONE_SIMULATOR 1 201 | #else 202 | #define GTM_IPHONE_DEVICE 1 203 | #endif // TARGET_IPHONE_SIMULATOR 204 | #else 205 | // For MacOS specific stuff 206 | #define GTM_MACOS_SDK 1 207 | #endif 208 | 209 | // Some of our own availability macros 210 | #if GTM_MACOS_SDK 211 | #define GTM_WEAK_ON_MACOS __weak 212 | #define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE 213 | #define GTM_AVAILABLE_ONLY_ON_MACOS 214 | #else 215 | #define GTM_WEAK_ON_MACOS 216 | #define GTM_AVAILABLE_ONLY_ON_IPHONE 217 | #define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE 218 | #endif 219 | 220 | // Provide a symbol to include/exclude extra code for GC support. (This mainly 221 | // just controls the inclusion of finalize methods). 222 | #ifndef GTM_SUPPORT_GC 223 | #if GTM_IPHONE_SDK 224 | // iPhone never needs GC 225 | #define GTM_SUPPORT_GC 0 226 | #else 227 | // We can't find a symbol to tell if GC is supported/required, so best we 228 | // do on Mac targets is include it if we're on 10.5 or later. 229 | #if GTM_MAC_OS_X_VERSION_MAXIMUM_ALLOWED <= MAC_OS_X_VERSION_10_4 230 | #define GTM_SUPPORT_GC 0 231 | #else 232 | #define GTM_SUPPORT_GC 1 233 | #endif 234 | #endif 235 | #endif 236 | 237 | // To simplify support for 64bit (and Leopard in general), we provide the type 238 | // defines for non Leopard SDKs 239 | #if GTM_MAC_OS_X_VERSION_MAXIMUM_ALLOWED <= MAC_OS_X_VERSION_10_4 240 | // NSInteger/NSUInteger and Max/Mins 241 | #ifndef NSINTEGER_DEFINED 242 | #if __LP64__ || NS_BUILD_32_LIKE_64 243 | typedef long NSInteger; 244 | typedef unsigned long NSUInteger; 245 | #else 246 | typedef int NSInteger; 247 | typedef unsigned int NSUInteger; 248 | #endif 249 | #define NSIntegerMax LONG_MAX 250 | #define NSIntegerMin LONG_MIN 251 | #define NSUIntegerMax ULONG_MAX 252 | #define NSINTEGER_DEFINED 1 253 | #endif // NSINTEGER_DEFINED 254 | // CGFloat 255 | #ifndef CGFLOAT_DEFINED 256 | #if defined(__LP64__) && __LP64__ 257 | // This really is an untested path (64bit on Tiger?) 258 | typedef double CGFloat; 259 | #define CGFLOAT_MIN DBL_MIN 260 | #define CGFLOAT_MAX DBL_MAX 261 | #define CGFLOAT_IS_DOUBLE 1 262 | #else /* !defined(__LP64__) || !__LP64__ */ 263 | typedef float CGFloat; 264 | #define CGFLOAT_MIN FLT_MIN 265 | #define CGFLOAT_MAX FLT_MAX 266 | #define CGFLOAT_IS_DOUBLE 0 267 | #endif /* !defined(__LP64__) || !__LP64__ */ 268 | #define CGFLOAT_DEFINED 1 269 | #endif // CGFLOAT_DEFINED 270 | #endif // GTM_MAC_OS_X_VERSION_MAXIMUM_ALLOWED <= MAC_OS_X_VERSION_10_4 271 | -------------------------------------------------------------------------------- /Framework/RSHTTPClientTestCase/GTMGarbageCollection.h: -------------------------------------------------------------------------------- 1 | // 2 | // GTMGarbageCollection.h 3 | // 4 | // Copyright 2007-2008 Google Inc. 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 7 | // use this file except in compliance with the License. You may obtain a copy 8 | // 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, WITHOUT 14 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | // License for the specific language governing permissions and limitations under 16 | // the License. 17 | // 18 | 19 | #import 20 | 21 | #import "GTMDefines.h" 22 | 23 | // This allows us to easily move our code from GC to non GC. 24 | // They are no-ops unless we are require Leopard or above. 25 | // See 26 | // http://developer.apple.com/documentation/Cocoa/Conceptual/GarbageCollection/index.html 27 | // and 28 | // http://developer.apple.com/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcCoreFoundation.html#//apple_ref/doc/uid/TP40006687-SW1 29 | // for details. 30 | 31 | #if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) && !GTM_IPHONE_SDK 32 | // General use would be to call this through GTMCFAutorelease 33 | // but there may be a reason the you want to make something collectable 34 | // but not autoreleased, especially in pure GC code where you don't 35 | // want to bother with the nop autorelease. Done as a define instead of an 36 | // inline so that tools like Clang's scan-build don't report code as leaking. 37 | #define GTMNSMakeCollectable(cf) ((id)NSMakeCollectable(cf)) 38 | 39 | // GTMNSMakeUncollectable is for global maps, etc. that we don't 40 | // want released ever. You should still retain these in non-gc code. 41 | GTM_INLINE void GTMNSMakeUncollectable(id object) { 42 | [[NSGarbageCollector defaultCollector] disableCollectorForPointer:object]; 43 | } 44 | 45 | // Hopefully no code really needs this, but GTMIsGarbageCollectionEnabled is 46 | // a common way to check at runtime if GC is on. 47 | // There are some places where GC doesn't work w/ things w/in Apple's 48 | // frameworks, so this is here so GTM unittests and detect it, and not run 49 | // individual tests to work around bugs in Apple's frameworks. 50 | GTM_INLINE BOOL GTMIsGarbageCollectionEnabled(void) { 51 | return ([NSGarbageCollector defaultCollector] != nil); 52 | } 53 | 54 | #else 55 | 56 | #define GTMNSMakeCollectable(cf) ((id)(cf)) 57 | 58 | GTM_INLINE void GTMNSMakeUncollectable(id object) { 59 | } 60 | 61 | GTM_INLINE BOOL GTMIsGarbageCollectionEnabled(void) { 62 | return NO; 63 | } 64 | 65 | #endif 66 | 67 | // GTMCFAutorelease makes a CF object collectable in GC mode, or adds it 68 | // to the autorelease pool in non-GC mode. Either way it is taken care 69 | // of. Done as a define instead of an inline so that tools like Clang's 70 | // scan-build don't report code as leaking. 71 | #define GTMCFAutorelease(cf) ([GTMNSMakeCollectable(cf) autorelease]) 72 | 73 | -------------------------------------------------------------------------------- /Framework/RSHTTPClientTestCase/GTMHTTPServer.h: -------------------------------------------------------------------------------- 1 | // 2 | // GTMHTTPServer.h 3 | // 4 | // This is a *very* *simple* webserver that can be built into something, it is 5 | // not meant to stand up a site, it sends all requests to its delegate for 6 | // processing on the main thread. It does not support pipelining, etc. It's 7 | // great for places where you need a simple webserver to unittest some code 8 | // that hits a server. 9 | // 10 | // NOTE: there are several TODOs left in here as markers for things that could 11 | // be done if one wanted to add more to this class. 12 | // 13 | // Copyright 2008 Google Inc. 14 | // 15 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 16 | // use this file except in compliance with the License. You may obtain a copy 17 | // of the License at 18 | // 19 | // http://www.apache.org/licenses/LICENSE-2.0 20 | // 21 | // Unless required by applicable law or agreed to in writing, software 22 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 23 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 24 | // License for the specific language governing permissions and limitations under 25 | // the License. 26 | // 27 | // Based a little on HTTPServer, part of the CocoaHTTPServer sample code 28 | // http://developer.apple.com/samplecode/CocoaHTTPServer/index.html 29 | // 30 | 31 | #import 32 | #import "GTMDefines.h" 33 | 34 | #if GTM_IPHONE_SDK 35 | #import 36 | #endif // GTM_IPHONE_SDK 37 | 38 | // Global contants needed for errors from start 39 | 40 | #undef _EXTERN 41 | #undef _INITIALIZE_AS 42 | #ifdef GTMHTTPSERVER_DEFINE_GLOBALS 43 | #define _EXTERN 44 | #define _INITIALIZE_AS(x) =x 45 | #else 46 | #define _EXTERN GTM_EXTERN 47 | #define _INITIALIZE_AS(x) 48 | #endif 49 | 50 | _EXTERN NSString* kGTMHTTPServerErrorDomain _INITIALIZE_AS(@"com.google.mactoolbox.HTTPServerDomain"); 51 | enum { 52 | kGTMHTTPServerSocketCreateFailedError = -100, 53 | kGTMHTTPServerBindFailedError = -101, 54 | kGTMHTTPServerListenFailedError = -102, 55 | kGTMHTTPServerHandleCreateFailedError = -103, 56 | }; 57 | 58 | @class GTMHTTPRequestMessage, GTMHTTPResponseMessage; 59 | 60 | // ---------------------------------------------------------------------------- 61 | 62 | // See comment at top of file for the intened use of this class. 63 | @interface GTMHTTPServer : NSObject { 64 | @private 65 | __weak id delegate_; 66 | uint16_t port_; 67 | BOOL localhostOnly_; 68 | NSFileHandle *listenHandle_; 69 | NSMutableArray *connections_; 70 | } 71 | 72 | // The delegate must support the httpServer:handleRequest: method in 73 | // NSObject(GTMHTTPServerDeletateMethods) below. 74 | - (id)initWithDelegate:(id)delegate; 75 | 76 | - (id)delegate; 77 | 78 | // Passing port zero will let one get assigned. 79 | - (uint16_t)port; 80 | - (void)setPort:(uint16_t)port; 81 | 82 | // Receive connections on the localHost loopback address only or on all 83 | // interfaces for this machine. The default is to only listen on localhost. 84 | - (BOOL)localhostOnly; 85 | - (void)setLocalhostOnly:(BOOL)yesno; 86 | 87 | // Start/Stop the web server. If there is an error starting up the server, |NO| 88 | // is returned, and the specific startup failure can be returned in |error| (see 89 | // above for the error domain and error codes). If the server is started, |YES| 90 | // is returned and the server's delegate is called for any requests that come 91 | // in. 92 | - (BOOL)start:(NSError **)error; 93 | - (void)stop; 94 | 95 | // returns the number of requests currently active in the server (i.e.-being 96 | // read in, sent replies). 97 | - (NSUInteger)activeRequestCount; 98 | 99 | @end 100 | 101 | @interface NSObject (GTMHTTPServerDeletateMethods) 102 | - (GTMHTTPResponseMessage *)httpServer:(GTMHTTPServer *)server 103 | handleRequest:(GTMHTTPRequestMessage *)request; 104 | @end 105 | 106 | // ---------------------------------------------------------------------------- 107 | 108 | // Encapsulates an http request, one of these is sent to the server's delegate 109 | // for each request. 110 | @interface GTMHTTPRequestMessage : NSObject { 111 | @private 112 | CFHTTPMessageRef message_; 113 | } 114 | - (NSString *)version; 115 | - (NSURL *)URL; 116 | - (NSString *)method; 117 | - (NSData *)body; 118 | - (NSDictionary *)allHeaderFieldValues; 119 | @end 120 | 121 | // ---------------------------------------------------------------------------- 122 | 123 | // Encapsulates an http response, the server's delegate should return one for 124 | // each request received. 125 | @interface GTMHTTPResponseMessage : NSObject { 126 | @private 127 | CFHTTPMessageRef message_; 128 | } 129 | + (id)responseWithHTMLString:(NSString *)htmlString; 130 | + (id)responseWithBody:(NSData *)body 131 | contentType:(NSString *)contentType 132 | statusCode:(int)statusCode; 133 | + (id)emptyResponseWithCode:(int)statusCode; 134 | // TODO: class method for redirections? 135 | // TODO: add helper for expire/no-cache 136 | - (void)setValue:(NSString*)value forHeaderField:(NSString*)headerField; 137 | @end 138 | -------------------------------------------------------------------------------- /Framework/RSHTTPClientTestCase/GTMHTTPServer.m: -------------------------------------------------------------------------------- 1 | // 2 | // GTMHTTPServer.m 3 | // 4 | // Copyright 2008 Google Inc. 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 7 | // use this file except in compliance with the License. You may obtain a copy 8 | // 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, WITHOUT 14 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | // License for the specific language governing permissions and limitations under 16 | // the License. 17 | // 18 | // Based a little on HTTPServer, part of the CocoaHTTPServer sample code 19 | // http://developer.apple.com/samplecode/CocoaHTTPServer/index.html 20 | // 21 | 22 | #import 23 | #import 24 | #import 25 | 26 | #define GTMHTTPSERVER_DEFINE_GLOBALS 27 | #import "GTMHTTPServer.h" 28 | #import "GTMDebugSelectorValidation.h" 29 | #import "GTMGarbageCollection.h" 30 | #import "GTMDefines.h" 31 | 32 | @interface GTMHTTPServer (PrivateMethods) 33 | - (void)acceptedConnectionNotification:(NSNotification *)notification; 34 | - (NSMutableDictionary *)connectionWithFileHandle:(NSFileHandle *)fileHandle; 35 | - (void)dataAvailableNotification:(NSNotification *)notification; 36 | - (NSMutableDictionary *)lookupConnection:(NSFileHandle *)fileHandle; 37 | - (void)closeConnection:(NSMutableDictionary *)connDict; 38 | - (void)sendResponseOnNewThread:(NSMutableDictionary *)connDict; 39 | - (void)sentResponse:(NSMutableDictionary *)connDict; 40 | @end 41 | 42 | // keys for our connection dictionaries 43 | static NSString *kFileHandle = @"FileHandle"; 44 | static NSString *kRequest = @"Request"; 45 | static NSString *kResponse = @"Response"; 46 | 47 | @interface GTMHTTPRequestMessage (PrivateHelpers) 48 | - (BOOL)isHeaderComplete; 49 | - (BOOL)appendData:(NSData *)data; 50 | - (NSString *)headerFieldValueForKey:(NSString *)key; 51 | - (UInt32)contentLength; 52 | - (void)setBody:(NSData *)body; 53 | @end 54 | 55 | @interface GTMHTTPResponseMessage (PrivateMethods) 56 | - (id)initWithBody:(NSData *)body 57 | contentType:(NSString *)contentType 58 | statusCode:(int)statusCode; 59 | - (NSData*)serializedData; 60 | @end 61 | 62 | @implementation GTMHTTPServer 63 | 64 | - (id)init { 65 | return [self initWithDelegate:nil]; 66 | } 67 | 68 | - (id)initWithDelegate:(id)delegate { 69 | self = [super init]; 70 | if (self) { 71 | if (!delegate) { 72 | _GTMDevLog(@"missing delegate"); 73 | [self release]; 74 | return nil; 75 | } 76 | delegate_ = delegate; 77 | GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(delegate_, 78 | @selector(httpServer:handleRequest:), 79 | // return type 80 | @encode(GTMHTTPResponseMessage *), 81 | // args 82 | @encode(GTMHTTPServer *), 83 | @encode(GTMHTTPRequestMessage *), 84 | NULL); 85 | localhostOnly_ = YES; 86 | connections_ = [[NSMutableArray alloc] init]; 87 | } 88 | return self; 89 | } 90 | 91 | - (void)dealloc { 92 | [self stop]; 93 | [connections_ release]; 94 | [super dealloc]; 95 | } 96 | 97 | #if GTM_SUPPORT_GC 98 | - (void)finalize { 99 | [self stop]; 100 | [super finalize]; 101 | } 102 | #endif 103 | 104 | - (id)delegate { 105 | return delegate_; 106 | } 107 | 108 | - (uint16_t)port { 109 | return port_; 110 | } 111 | 112 | - (void)setPort:(uint16_t)port { 113 | port_ = port; 114 | } 115 | 116 | - (BOOL)localhostOnly { 117 | return localhostOnly_; 118 | } 119 | 120 | - (void)setLocalhostOnly:(BOOL)yesno { 121 | localhostOnly_ = yesno; 122 | } 123 | 124 | - (BOOL)start:(NSError **)error { 125 | _GTMDevAssert(listenHandle_ == nil, 126 | @"start called when we already have a listenHandle_"); 127 | 128 | if (error) *error = NULL; 129 | 130 | NSInteger startFailureCode = 0; 131 | int fd = socket(AF_INET, SOCK_STREAM, 0); 132 | if (fd <= 0) { 133 | // COV_NF_START - we'd need to use up *all* sockets to test this? 134 | startFailureCode = kGTMHTTPServerSocketCreateFailedError; 135 | goto startFailed; 136 | // COV_NF_END 137 | } 138 | 139 | // enable address reuse quicker after we are done w/ our socket 140 | int yes = 1; 141 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 142 | (void *)&yes, (socklen_t)sizeof(yes)) != 0) { 143 | _GTMDevLog(@"failed to mark the socket as reusable"); // COV_NF_LINE 144 | } 145 | 146 | // bind 147 | struct sockaddr_in addr; 148 | bzero(&addr, sizeof(addr)); 149 | addr.sin_len = sizeof(addr); 150 | addr.sin_family = AF_INET; 151 | addr.sin_port = htons(port_); 152 | if (localhostOnly_) { 153 | addr.sin_addr.s_addr = htonl(0x7F000001); 154 | } else { 155 | // COV_NF_START - testing this could cause a leopard firewall prompt during tests. 156 | addr.sin_addr.s_addr = htonl(INADDR_ANY); 157 | // COV_NF_END 158 | } 159 | if (bind(fd, (struct sockaddr*)(&addr), (socklen_t)sizeof(addr)) != 0) { 160 | startFailureCode = kGTMHTTPServerBindFailedError; 161 | goto startFailed; 162 | } 163 | 164 | // collect the port back out 165 | if (port_ == 0) { 166 | socklen_t len = (socklen_t)sizeof(addr); 167 | if (getsockname(fd, (struct sockaddr*)(&addr), &len) == 0) { 168 | port_ = ntohs(addr.sin_port); 169 | } 170 | } 171 | 172 | // tell it to listen for connections 173 | if (listen(fd, 5) != 0) { 174 | // COV_NF_START 175 | startFailureCode = kGTMHTTPServerListenFailedError; 176 | goto startFailed; 177 | // COV_NF_END 178 | } 179 | 180 | // now use a filehandle to accept connections 181 | listenHandle_ = 182 | [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES]; 183 | if (listenHandle_ == nil) { 184 | // COV_NF_START - we'd need to run out of memory to test this? 185 | startFailureCode = kGTMHTTPServerHandleCreateFailedError; 186 | goto startFailed; 187 | // COV_NF_END 188 | } 189 | 190 | // setup notifications for connects 191 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 192 | [center addObserver:self 193 | selector:@selector(acceptedConnectionNotification:) 194 | name:NSFileHandleConnectionAcceptedNotification 195 | object:listenHandle_]; 196 | [listenHandle_ acceptConnectionInBackgroundAndNotify]; 197 | 198 | // TODO: maybe hit the delegate incase it wants to register w/ NSNetService, 199 | // or just know we're up and running? 200 | 201 | return YES; 202 | 203 | startFailed: 204 | if (error) { 205 | *error = [[[NSError alloc] initWithDomain:kGTMHTTPServerErrorDomain 206 | code:startFailureCode 207 | userInfo:nil] autorelease]; 208 | } 209 | if (fd > 0) { 210 | close(fd); 211 | } 212 | return NO; 213 | } 214 | 215 | - (void)stop { 216 | if (listenHandle_) { 217 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 218 | [center removeObserver:self 219 | name:NSFileHandleConnectionAcceptedNotification 220 | object:listenHandle_]; 221 | [listenHandle_ release]; 222 | listenHandle_ = nil; 223 | // TODO: maybe hit the delegate in case it wants to unregister w/ 224 | // NSNetService, or just know we've stopped running? 225 | } 226 | [connections_ removeAllObjects]; 227 | } 228 | 229 | - (NSUInteger)activeRequestCount { 230 | return [connections_ count]; 231 | } 232 | 233 | - (NSString *)description { 234 | NSString *result = 235 | [NSString stringWithFormat:@"%@<%p>{ port=%d localHostOnly=%@ status=%@ }", 236 | [self class], self, port_, (localhostOnly_ ? @"YES" : @"NO"), 237 | (listenHandle_ != nil ? @"Started" : @"Stopped") ]; 238 | return result; 239 | } 240 | 241 | 242 | @end 243 | 244 | @implementation GTMHTTPServer (PrivateMethods) 245 | 246 | - (void)acceptedConnectionNotification:(NSNotification *)notification { 247 | NSDictionary *userInfo = [notification userInfo]; 248 | NSFileHandle *newConnection = 249 | [userInfo objectForKey:NSFileHandleNotificationFileHandleItem]; 250 | _GTMDevAssert(newConnection != nil, 251 | @"failed to get the connection in the notification: %@", 252 | notification); 253 | 254 | // make sure we accept more... 255 | [listenHandle_ acceptConnectionInBackgroundAndNotify]; 256 | 257 | // TODO: could let the delegate look at the address, before we start working 258 | // on it. 259 | 260 | NSMutableDictionary *connDict = 261 | [self connectionWithFileHandle:newConnection]; 262 | [connections_ addObject:connDict]; 263 | } 264 | 265 | - (NSMutableDictionary *)connectionWithFileHandle:(NSFileHandle *)fileHandle { 266 | NSMutableDictionary *result = [NSMutableDictionary dictionary]; 267 | 268 | [result setObject:fileHandle forKey:kFileHandle]; 269 | 270 | GTMHTTPRequestMessage *request = 271 | [[[GTMHTTPRequestMessage alloc] init] autorelease]; 272 | [result setObject:request forKey:kRequest]; 273 | 274 | // setup for data notifications 275 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 276 | [center addObserver:self 277 | selector:@selector(dataAvailableNotification:) 278 | name:NSFileHandleReadCompletionNotification 279 | object:fileHandle]; 280 | [fileHandle readInBackgroundAndNotify]; 281 | 282 | return result; 283 | } 284 | 285 | - (void)dataAvailableNotification:(NSNotification *)notification { 286 | NSFileHandle *connectionHandle = [notification object]; 287 | NSMutableDictionary *connDict = [self lookupConnection:connectionHandle]; 288 | if (connDict == nil) return; // we are no longer tracking this one 289 | 290 | NSDictionary *userInfo = [notification userInfo]; 291 | NSData *readData = [userInfo objectForKey:NSFileHandleNotificationDataItem]; 292 | if ([readData length] == 0) { 293 | // remote side closed 294 | [self closeConnection:connDict]; 295 | return; 296 | } 297 | 298 | // Use a local pool to keep memory down incase the runloop we're in doesn't 299 | // drain until it gets a UI event. 300 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 301 | @try { 302 | // Like Apple's sample, we just keep adding data until we get a full header 303 | // and any referenced body. 304 | 305 | GTMHTTPRequestMessage *request = [connDict objectForKey:kRequest]; 306 | [request appendData:readData]; 307 | 308 | // Is the header complete yet? 309 | if (![request isHeaderComplete]) { 310 | // more data... 311 | [connectionHandle readInBackgroundAndNotify]; 312 | } else { 313 | 314 | // Do we have all the body? 315 | UInt32 contentLength = [request contentLength]; 316 | NSData *body = [request body]; 317 | NSUInteger bodyLength = [body length]; 318 | if (contentLength > bodyLength) { 319 | // need more data... 320 | [connectionHandle readInBackgroundAndNotify]; 321 | } else { 322 | 323 | if (contentLength < bodyLength) { 324 | // We got extra (probably someone trying to pipeline on us), trim 325 | // and let the extra data go... 326 | NSData *newBody = [NSData dataWithBytes:[body bytes] 327 | length:contentLength]; 328 | [request setBody:newBody]; 329 | _GTMDevLog(@"Got %lu extra bytes on http request, ignoring them", 330 | (unsigned long)(bodyLength - contentLength)); 331 | } 332 | 333 | GTMHTTPResponseMessage *response = nil; 334 | @try { 335 | // Off to the delegate 336 | response = [delegate_ httpServer:self handleRequest:request]; 337 | } @catch (NSException *e) { 338 | _GTMDevLog(@"Exception trying to handle http request: %@", e); 339 | } // COV_NF_LINE - radar 5851992 only reachable w/ an uncaught exception which isn't testable 340 | 341 | if (response) { 342 | // We don't support connection reuse, so we add (force) the header to 343 | // close every connection. 344 | [response setValue:@"close" forHeaderField:@"Connection"]; 345 | 346 | // spawn thread to send reply (since we do a blocking send) 347 | [connDict setObject:response forKey:kResponse]; 348 | [NSThread detachNewThreadSelector:@selector(sendResponseOnNewThread:) 349 | toTarget:self 350 | withObject:connDict]; 351 | } else { 352 | // No response, shut it down 353 | [self closeConnection:connDict]; 354 | } 355 | 356 | } 357 | } 358 | } @catch (NSException *e) { // COV_NF_START 359 | _GTMDevLog(@"exception while read data: %@", e); 360 | // exception while dealing with the connection, close it 361 | } // COV_NF_END 362 | @finally { 363 | [pool drain]; 364 | } 365 | } 366 | 367 | - (NSMutableDictionary *)lookupConnection:(NSFileHandle *)fileHandle { 368 | NSMutableDictionary *result = nil; 369 | NSMutableDictionary *connDict; 370 | GTM_FOREACH_OBJECT(connDict, connections_) { 371 | if (fileHandle == [connDict objectForKey:kFileHandle]) { 372 | result = connDict; 373 | break; 374 | } 375 | } 376 | return result; 377 | } 378 | 379 | - (void)closeConnection:(NSMutableDictionary *)connDict { 380 | // remove the notification 381 | NSFileHandle *connectionHandle = [connDict objectForKey:kFileHandle]; 382 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 383 | [center removeObserver:self 384 | name:NSFileHandleReadCompletionNotification 385 | object:connectionHandle]; 386 | // in a non GC world, we're fine just letting the connect get closed when 387 | // the object is release when it comes out of connections_, but in a GC world 388 | // it won't get cleaned up 389 | [connectionHandle closeFile]; 390 | 391 | // remove it from the list 392 | [connections_ removeObject:connDict]; 393 | } 394 | 395 | - (void)sendResponseOnNewThread:(NSMutableDictionary *)connDict { 396 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 397 | 398 | @try { 399 | GTMHTTPResponseMessage *response = [connDict objectForKey:kResponse]; 400 | NSFileHandle *connectionHandle = [connDict objectForKey:kFileHandle]; 401 | NSData *serialized = [response serializedData]; 402 | [connectionHandle writeData:serialized]; 403 | } @catch (NSException *e) { // COV_NF_START - causing an exception here is to hard in a test 404 | // TODO: let the delegate know about the exception (but do it on the main 405 | // thread) 406 | _GTMDevLog(@"exception while sending reply: %@", e); 407 | } // COV_NF_END 408 | 409 | // back to the main thread to close things down 410 | [self performSelectorOnMainThread:@selector(sentResponse:) 411 | withObject:connDict 412 | waitUntilDone:NO]; 413 | 414 | [pool release]; 415 | } 416 | 417 | - (void)sentResponse:(NSMutableDictionary *)connDict { 418 | // make sure we're still tracking this connection (in case server was stopped) 419 | NSFileHandle *connection = [connDict objectForKey:kFileHandle]; 420 | NSMutableDictionary *connDict2 = [self lookupConnection:connection]; 421 | if (connDict != connDict2) return; 422 | 423 | // TODO: message the delegate that it was sent 424 | 425 | // close it down 426 | [self closeConnection:connDict]; 427 | } 428 | 429 | @end 430 | 431 | #pragma mark - 432 | 433 | @implementation GTMHTTPRequestMessage 434 | 435 | - (id)init { 436 | self = [super init]; 437 | if (self) { 438 | message_ = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, YES); 439 | } 440 | return self; 441 | } 442 | 443 | - (void)dealloc { 444 | if (message_) { 445 | CFRelease(message_); 446 | } 447 | [super dealloc]; 448 | } 449 | 450 | - (NSString *)version { 451 | return GTMCFAutorelease(CFHTTPMessageCopyVersion(message_)); 452 | } 453 | 454 | - (NSURL *)URL { 455 | return GTMCFAutorelease(CFHTTPMessageCopyRequestURL(message_)); 456 | } 457 | 458 | - (NSString *)method { 459 | return GTMCFAutorelease(CFHTTPMessageCopyRequestMethod(message_)); 460 | } 461 | 462 | - (NSData *)body { 463 | return GTMCFAutorelease(CFHTTPMessageCopyBody(message_)); 464 | } 465 | 466 | - (NSDictionary *)allHeaderFieldValues { 467 | return GTMCFAutorelease(CFHTTPMessageCopyAllHeaderFields(message_)); 468 | } 469 | 470 | - (NSString *)description { 471 | CFStringRef desc = CFCopyDescription(message_); 472 | NSString *result = 473 | [NSString stringWithFormat:@"%@<%p>{ message=%@ }", [self class], self, desc]; 474 | CFRelease(desc); 475 | return result; 476 | } 477 | 478 | @end 479 | 480 | @implementation GTMHTTPRequestMessage (PrivateHelpers) 481 | 482 | - (BOOL)isHeaderComplete { 483 | return CFHTTPMessageIsHeaderComplete(message_) ? YES : NO; 484 | } 485 | 486 | - (BOOL)appendData:(NSData *)data { 487 | return CFHTTPMessageAppendBytes(message_, 488 | [data bytes], [data length]) ? YES : NO; 489 | } 490 | 491 | - (NSString *)headerFieldValueForKey:(NSString *)key { 492 | CFStringRef value = NULL; 493 | if (key) { 494 | value = CFHTTPMessageCopyHeaderFieldValue(message_, (CFStringRef)key); 495 | } 496 | return GTMCFAutorelease(value); 497 | } 498 | 499 | - (UInt32)contentLength { 500 | return [[self headerFieldValueForKey:@"Content-Length"] intValue]; 501 | } 502 | 503 | - (void)setBody:(NSData *)body { 504 | if (!body) { 505 | body = [NSData data]; // COV_NF_LINE - can only happen in we fail to make the new data object 506 | } 507 | CFHTTPMessageSetBody(message_, (CFDataRef)body); 508 | } 509 | 510 | @end 511 | 512 | #pragma mark - 513 | 514 | @implementation GTMHTTPResponseMessage 515 | 516 | - (id)init { 517 | return [self initWithBody:nil contentType:nil statusCode:0]; 518 | } 519 | 520 | - (void)dealloc { 521 | if (message_) { 522 | CFRelease(message_); 523 | } 524 | [super dealloc]; 525 | } 526 | 527 | + (id)responseWithHTMLString:(NSString *)htmlString { 528 | return [self responseWithBody:[htmlString dataUsingEncoding:NSUTF8StringEncoding] 529 | contentType:@"text/html; charset=UTF-8" 530 | statusCode:200]; 531 | } 532 | 533 | + (id)responseWithBody:(NSData *)body 534 | contentType:(NSString *)contentType 535 | statusCode:(int)statusCode { 536 | return [[[[self class] alloc] initWithBody:body 537 | contentType:contentType 538 | statusCode:statusCode] autorelease]; 539 | } 540 | 541 | + (id)emptyResponseWithCode:(int)statusCode { 542 | return [[[[self class] alloc] initWithBody:nil 543 | contentType:nil 544 | statusCode:statusCode] autorelease]; 545 | } 546 | 547 | - (void)setValue:(NSString*)value forHeaderField:(NSString*)headerField { 548 | if ([headerField length] == 0) return; 549 | if (value == nil) { 550 | value = @""; 551 | } 552 | CFHTTPMessageSetHeaderFieldValue(message_, 553 | (CFStringRef)headerField, (CFStringRef)value); 554 | } 555 | 556 | - (NSString *)description { 557 | CFStringRef desc = CFCopyDescription(message_); 558 | NSString *result = 559 | [NSString stringWithFormat:@"%@<%p>{ message=%@ }", [self class], self, desc]; 560 | CFRelease(desc); 561 | return result; 562 | } 563 | 564 | @end 565 | 566 | @implementation GTMHTTPResponseMessage (PrivateMethods) 567 | 568 | - (id)initWithBody:(NSData *)body 569 | contentType:(NSString *)contentType 570 | statusCode:(int)statusCode { 571 | self = [super init]; 572 | if (self) { 573 | if ((statusCode < 100) || (statusCode > 599)) { 574 | [self release]; 575 | return nil; 576 | } 577 | message_ = CFHTTPMessageCreateResponse(kCFAllocatorDefault, 578 | statusCode, NULL, 579 | kCFHTTPVersion1_0); 580 | if (!message_) { 581 | // COV_NF_START 582 | [self release]; 583 | return nil; 584 | // COV_NF_END 585 | } 586 | NSUInteger bodyLength = 0; 587 | if (body) { 588 | bodyLength = [body length]; 589 | CFHTTPMessageSetBody(message_, (CFDataRef)body); 590 | } 591 | if ([contentType length] == 0) { 592 | contentType = @"text/html"; 593 | } 594 | NSString *bodyLenStr = 595 | [NSString stringWithFormat:@"%lu", (unsigned long)bodyLength]; 596 | [self setValue:bodyLenStr forHeaderField:@"Content-Length"]; 597 | [self setValue:contentType forHeaderField:@"Content-Type"]; 598 | } 599 | return self; 600 | } 601 | 602 | - (NSData *)serializedData { 603 | return GTMCFAutorelease(CFHTTPMessageCopySerializedMessage(message_)); 604 | } 605 | 606 | @end 607 | -------------------------------------------------------------------------------- /Framework/RSHTTPClientTestCase/RSHTTPClientTestCase.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSHTTPClientTestCase.h 3 | // MarsEdit 4 | // 5 | // Provides common testing infrastructure to test cases where an artificial 6 | // HTTP server is run from within the test case, in order to accept expected 7 | // connections and to serve expected results. 8 | // 9 | // Created by Daniel Jalkut on 3/20/09. 10 | // Copyright 2009 Red Sweater Software. All rights reserved. 11 | // 12 | // You are granted the right to copy and use this code under the MIT license. See License.txt for more. 13 | // 14 | 15 | #import 16 | 17 | @class GTMHTTPServer; 18 | @class GTMHTTPRequestMessage; 19 | @class GTMHTTPResponseMessage; 20 | 21 | @interface RSHTTPClientTestCase : RSRunLoopWaitingTestCase 22 | { 23 | GTMHTTPServer* mTestServer; 24 | } 25 | 26 | // For subclass access, mainly 27 | - (GTMHTTPServer *) testServer; 28 | - (void) setTestServer: (GTMHTTPServer *) theTestServer; 29 | 30 | // These facilitate no-nonsense generation of test URLs that convey 31 | // the desired test behavior from the client to the "server". Essentially 32 | // just an easy way of encoding the test by name into a URL that will get 33 | // any HTTP request from the client directed to the test server we are running. 34 | 35 | - (NSURL*) serverURLForHTTPTestNamed:(NSString*)testName; 36 | - (NSString*) testNameFromServerURL:(NSURL*)theTestURL; 37 | 38 | // Subclasses should implement this GTMHTTPServer delegate method only if they 39 | // need to customize behavior of the HTTP server beyond what we provide by default. 40 | // 41 | // By default, you don't need to implement this. Just implement a method for each of your 42 | // named tests which conforms to the naming convention, e.g., for a test "basic": 43 | // 44 | // - (GTMHTTPResponseMessage *) responseForTestRequest_basic:(GTMHTTPRequestMessage *)request; 45 | // 46 | // Using this facility makes it easier to let your test server response conditions live in methods 47 | // very close to the test client code. 48 | // 49 | - (GTMHTTPResponseMessage *)httpServer:(GTMHTTPServer *)server handleRequest:(GTMHTTPRequestMessage *)request; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Framework/RSHTTPClientTestCase/RSHTTPClientTestCase.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSHTTPClientTestCase.m 3 | // MarsEdit 4 | // 5 | // Created by Daniel Jalkut on 3/20/09. 6 | // Copyright 2009 Red Sweater Software. All rights reserved. 7 | // 8 | // You are granted the right to copy and use this code under the MIT license. See License.txt for more. 9 | // 10 | 11 | #import "RSHTTPClientTestCase.h" 12 | #import "GTMHTTPServer.h" 13 | 14 | @implementation RSHTTPClientTestCase 15 | 16 | - (void) setUp 17 | { 18 | [super setUp]; 19 | 20 | mTestServer = [[GTMHTTPServer alloc] initWithDelegate:self]; 21 | [mTestServer setPort:0]; 22 | NSError* serverErr = nil; 23 | [mTestServer start:&serverErr]; 24 | } 25 | 26 | - (void) tearDown 27 | { 28 | [mTestServer stop]; 29 | [mTestServer release]; 30 | 31 | [super tearDown]; 32 | } 33 | 34 | - (NSURL*) serverURLForHTTPTestNamed:(NSString*)testName 35 | { 36 | NSString* urlString = [NSString stringWithFormat:@"http://localhost:%d/%@", [[self testServer] port], testName]; 37 | return [NSURL URLWithString:urlString]; 38 | } 39 | 40 | - (NSString*) testNameFromServerURL:(NSURL*)theTestURL 41 | { 42 | return [[theTestURL path] substringFromIndex:1]; // the path minus the leading "/" 43 | } 44 | 45 | // testServer 46 | - (GTMHTTPServer *) testServer 47 | { 48 | return mTestServer; 49 | } 50 | 51 | - (void) setTestServer: (GTMHTTPServer *) theTestServer 52 | { 53 | if (mTestServer != theTestServer) 54 | { 55 | [mTestServer release]; 56 | mTestServer = [theTestServer retain]; 57 | } 58 | } 59 | 60 | // the default test-server delegate attempts to dispatch to a server response method named appropriately for the test name 61 | - (GTMHTTPResponseMessage *)httpServer:(GTMHTTPServer *)server handleRequest:(GTMHTTPRequestMessage *)request 62 | { 63 | NSString* thisTestName = [self testNameFromServerURL:[request URL]]; 64 | NSString* requestResponseMethodName = [NSString stringWithFormat:@"responseForTestRequest_%@:", thisTestName]; 65 | SEL responseSelector = NSSelectorFromString(requestResponseMethodName); 66 | 67 | // If we (i.e. the specific test subclass) respond to the method, use it. Otherwise we fake a 404 response. 68 | if ([self respondsToSelector:responseSelector]) 69 | { 70 | return [self performSelector:responseSelector withObject:request]; 71 | } 72 | else 73 | { 74 | return [GTMHTTPResponseMessage responseWithBody:[@"Test URL not handled" dataUsingEncoding:NSUTF8StringEncoding] contentType:@"text/plain" statusCode:404]; 75 | } 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Framework/RSRunLoopWaitingTestCase.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSRunLoopWaitingTestCase.h 3 | // RSCommon 4 | // 5 | // Created by Daniel Jalkut on 9/10/08. 6 | // Copyright 2008 Red Sweater Software. All rights reserved. 7 | // 8 | // You are granted the right to copy and use this code under the MIT license. See License.txt for more. 9 | // 10 | 11 | // Provides common testing infrastructure to test cases where real time must be 12 | // spent running the runloop and waiting for a conclusion flag to turn true. 13 | // 14 | // The "test" methods can for instance: 15 | // 16 | // [self setTimeoutFailureContextString:@"Waiting for Godot"]; 17 | // [self performWaitingForGodotTest]; 18 | // [self waitForRunLoopTestCompletion]; 19 | // 20 | // The "performWaitingForGodotTest" spawn a runloop-driven whose callback promises to 21 | // to call [self setWaitingForTestCompletion:NO]; 22 | // 23 | 24 | #import 25 | 26 | @interface RSRunLoopWaitingTestCase : RSTestCase 27 | { 28 | BOOL mWaitingForTestCompletion; 29 | 30 | NSTimeInterval mTestCompletionTimeout; 31 | 32 | // What error string should we communicate when we fail from timeout? 33 | NSString* mTimeoutFailureContextString; 34 | } 35 | 36 | // How long will we run the loop before giving up and failing the test? 37 | - (NSTimeInterval) testCompletionTimeout; 38 | - (void) setTestCompletionTimeout: (NSTimeInterval) theTestCompletionTimeout; 39 | 40 | - (NSString *) timeoutFailureContextString; 41 | - (void) setTimeoutFailureContextString: (NSString *) theTimeoutFailureContextString; 42 | 43 | - (void) waitForRunLoopTestCompletion; 44 | 45 | - (BOOL) waitingForTestCompletion; 46 | - (void) setWaitingForTestCompletion: (BOOL) flag; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Framework/RSRunLoopWaitingTestCase.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSRunLoopWaitingTestCase.m 3 | // RSCommon 4 | // 5 | // Created by Daniel Jalkut on 9/10/08. 6 | // Copyright 2008 Red Sweater Software. All rights reserved. 7 | // 8 | // You are granted the right to copy and use this code under the MIT license. See License.txt for more. 9 | // 10 | 11 | #import 12 | 13 | // Could be parameterized like the completion timeout but I haven't found a need yet 14 | static CGFloat kRunLoopIterationTimerInterval = 0.2; 15 | 16 | @implementation RSRunLoopWaitingTestCase 17 | 18 | - (void) commonInit 19 | { 20 | // Default to timing out long tests after 10 seconds 21 | mTestCompletionTimeout = 10.0; 22 | } 23 | 24 | - (id) initWithInvocation:(NSInvocation*)theInvocation 25 | { 26 | self = [super initWithInvocation:theInvocation]; 27 | if (self != nil) 28 | { 29 | [self commonInit]; 30 | } 31 | return self; 32 | } 33 | 34 | - (id) initWithSelector:(SEL)theSelector 35 | { 36 | self = [super initWithSelector:theSelector]; 37 | if (self != nil) 38 | { 39 | [self commonInit]; 40 | } 41 | return self; 42 | } 43 | 44 | - (void) dealloc 45 | { 46 | [mTimeoutFailureContextString release]; 47 | 48 | [super dealloc]; 49 | } 50 | 51 | // waitingForTestCompletion 52 | - (BOOL) waitingForTestCompletion 53 | { 54 | return mWaitingForTestCompletion; 55 | } 56 | 57 | - (void) setWaitingForTestCompletion: (BOOL) flag 58 | { 59 | mWaitingForTestCompletion = flag; 60 | } 61 | 62 | // testCompletionTimeout 63 | - (NSTimeInterval) testCompletionTimeout 64 | { 65 | return mTestCompletionTimeout; 66 | } 67 | 68 | - (void) setTestCompletionTimeout: (NSTimeInterval) theTestCompletionTimeout 69 | { 70 | mTestCompletionTimeout = theTestCompletionTimeout; 71 | } 72 | 73 | // timeoutFailureContextString 74 | - (NSString *) timeoutFailureContextString 75 | { 76 | return mTimeoutFailureContextString; 77 | } 78 | 79 | - (void) setTimeoutFailureContextString: (NSString *) theTimeoutFailureContextString 80 | { 81 | if (mTimeoutFailureContextString != theTimeoutFailureContextString) 82 | { 83 | [mTimeoutFailureContextString release]; 84 | mTimeoutFailureContextString = [theTimeoutFailureContextString retain]; 85 | } 86 | } 87 | 88 | - (void) waitForRunLoopTestCompletion 89 | { 90 | [self setWaitingForTestCompletion:YES]; 91 | 92 | // Wait for the download to finish 93 | NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate]; 94 | while ([self waitingForTestCompletion] == YES) 95 | { 96 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:kRunLoopIterationTimerInterval]]; 97 | 98 | // Don't let the download take longer than we're allowed 99 | NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceReferenceDate] - startTime; 100 | if (elapsedTime > (mTestCompletionTimeout)) 101 | { 102 | NSString* failContext = [self timeoutFailureContextString]; 103 | if (failContext == nil) 104 | { 105 | failContext = @"Timed out trying to perform test."; 106 | } 107 | NSString* testFailString = [NSString stringWithFormat:@"%@ %@", failContext, @"DCJ - Get more info about the running test in here?"]; 108 | STAssertTrue(0, testFailString); 109 | [self setWaitingForTestCompletion:NO]; 110 | break; 111 | } 112 | } 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /Framework/RSTestCase.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSTestCase.h 3 | // RSCommonLib 4 | // 5 | // Created by daniel on 8/21/09. 6 | // Copyright 2009 Red Sweater Software. All rights reserved. 7 | // 8 | // You are granted the right to copy and use this code under the MIT license. See License.txt for more. 9 | // 10 | 11 | #import 12 | 13 | @interface RSTestCase : SenTestCase 14 | { 15 | NSString* mTemporaryFolder; 16 | } 17 | 18 | // A folder that is appropriate for sandbox test file writing/reading. Will be removed when tests are completed. 19 | - (NSString*) pathToTemporaryFolder; 20 | 21 | // Returns the path to the folder from wihich test input files will be loaded. By default, 22 | // these are located in the test bundle's resources folder, inside a folder named "TestInputs" 23 | - (NSString*) pathForTestInputs; 24 | 25 | // Returns a path to the test input file of a given name. 26 | - (NSString*) pathForTestInputFilename:(NSString*)filename; 27 | - (NSString*) stringFromTestInputFilename:(NSString*)filename; 28 | - (NSData*) dataFromTestInputFilename:(NSString*)filename; 29 | 30 | @end 31 | 32 | // Add some convenience macros of our own 33 | 34 | #define RSAssertMatchingStrings(actualString, expectedString, comment) \ 35 | do { \ 36 | STAssertTrue([actualString isEqualToString:expectedString], @"%@: expected %@ got %@", comment, expectedString, actualString);\ 37 | } while (0) 38 | 39 | #define RSAssertFileExists(filePath, description, ...) \ 40 | do { \ 41 | @try {\ 42 | id filePathValue = (filePath); \ 43 | if ([[NSFileManager defaultManager] fileExistsAtPath:filePathValue] == NO) { \ 44 | [self failWithException:([NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \ 45 | atLine:__LINE__ \ 46 | withDescription:@"%@", [@"File does not exist: " stringByAppendingString:STComposeString(description, ##__VA_ARGS__)]])]; \ 47 | } \ 48 | }\ 49 | @catch (id anException) {\ 50 | [self failWithException:([NSException failureInRaise:[NSString stringWithFormat:@"fileExistsAtPath:(%s)", #filePath] \ 51 | exception:anException \ 52 | inFile:[NSString stringWithUTF8String:__FILE__] \ 53 | atLine:__LINE__ \ 54 | withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \ 55 | }\ 56 | } while(0) 57 | 58 | #define RSAssertFileDoesNotExist(filePath, description, ...) \ 59 | do { \ 60 | @try {\ 61 | id filePathValue = (filePath); \ 62 | if ([[NSFileManager defaultManager] fileExistsAtPath:filePathValue] == YES) { \ 63 | [self failWithException:([NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \ 64 | atLine:__LINE__ \ 65 | withDescription:@"%@", [@"File does exist: " stringByAppendingString:STComposeString(description, ##__VA_ARGS__)]])]; \ 66 | } \ 67 | }\ 68 | @catch (id anException) {\ 69 | [self failWithException:([NSException failureInRaise:[NSString stringWithFormat:@"fileExistsAtPath:(%s)", #filePath] \ 70 | exception:anException \ 71 | inFile:[NSString stringWithUTF8String:__FILE__] \ 72 | atLine:__LINE__ \ 73 | withDescription:@"%@", STComposeString(description, ##__VA_ARGS__)])]; \ 74 | }\ 75 | } while(0) 76 | 77 | -------------------------------------------------------------------------------- /Framework/RSTestCase.m: -------------------------------------------------------------------------------- 1 | // 2 | // RSTestCase.m 3 | // RSCommonLib 4 | // 5 | // Created by daniel on 8/21/09. 6 | // Copyright 2009 Red Sweater Software. All rights reserved. 7 | // 8 | // You are granted the right to copy and use this code under the MIT license. See License.txt for more. 9 | // 10 | 11 | #import "RSTestCase.h" 12 | 13 | @implementation RSTestCase 14 | 15 | - (void) tearDown 16 | { 17 | // If we created a temporary folder for our testing purposes, delete it now 18 | if (mTemporaryFolder != nil) 19 | { 20 | #if defined(MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 21 | (void) [[NSFileManager defaultManager] removeItemAtPath:mTemporaryFolder error:nil]; 22 | #else 23 | (void) [[NSFileManager defaultManager] removeFileAtPath:mTemporaryFolder handler:nil]; 24 | #endif 25 | [mTemporaryFolder release]; 26 | mTemporaryFolder = nil; 27 | } 28 | 29 | [super tearDown]; 30 | } 31 | 32 | - (void) dealloc 33 | { 34 | [mTemporaryFolder release]; 35 | [super dealloc]; 36 | } 37 | 38 | - (NSString *) uniqueIdentifierString 39 | { 40 | NSString *uniqueIDString; 41 | 42 | CFUUIDRef cfUUIDObject = CFUUIDCreate(kCFAllocatorDefault); 43 | uniqueIDString = (NSString *) CFUUIDCreateString(kCFAllocatorDefault, cfUUIDObject); 44 | CFRelease(cfUUIDObject); 45 | 46 | return [uniqueIDString autorelease]; 47 | } 48 | 49 | - (BOOL) simpleCreateDirectoryAtPath:(NSString*)thePath withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary*)attributes 50 | { 51 | #if defined(MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 52 | return [[NSFileManager defaultManager] createDirectoryAtPath:thePath withIntermediateDirectories:createIntermediates attributes:attributes error:nil]; 53 | #else 54 | BOOL success = YES; 55 | 56 | if (createIntermediates == YES) 57 | { 58 | NSMutableArray* missingParents = [NSMutableArray array]; 59 | NSString* missingParent = thePath; 60 | while ([[NSFileManager defaultManager] fileExistsAtPath:missingParent] == NO) 61 | { 62 | [missingParents insertObject:missingParent atIndex:0]; 63 | missingParent = [missingParent stringByDeletingLastPathComponent]; 64 | if (([missingParent length] == 0) || ([missingParent isEqualToString:@"/"])) 65 | { 66 | break; 67 | } 68 | } 69 | 70 | NSEnumerator* missingEnum = [missingParents objectEnumerator]; 71 | while (missingParent = [missingEnum nextObject]) 72 | { 73 | success = [[NSFileManager defaultManager] createDirectoryAtPath:missingParent attributes:attributes]; 74 | if (success == NO) 75 | { 76 | break; 77 | } 78 | } 79 | } 80 | else 81 | { 82 | success = [[NSFileManager defaultManager] createDirectoryAtPath:thePath attributes:nil]; 83 | } 84 | return success; 85 | #endif 86 | } 87 | 88 | - (BOOL) simpleCreateDirectoryAtPath:(NSString*)thePath withIntermediateDirectories:(BOOL)createIntermediates 89 | { 90 | return [self simpleCreateDirectoryAtPath:thePath withIntermediateDirectories:createIntermediates attributes:nil]; 91 | } 92 | 93 | - (BOOL) simpleCreateDirectoryAtPath:(NSString*)thePath 94 | { 95 | return [self simpleCreateDirectoryAtPath:thePath withIntermediateDirectories:YES]; 96 | } 97 | 98 | - (NSString*) pathToTemporaryFolder 99 | { 100 | if (mTemporaryFolder == nil) 101 | { 102 | // Guard against possibility for NSTemporaryDirectory to return nil 103 | NSString* tempFolderParent = NSTemporaryDirectory(); 104 | if (tempFolderParent == nil) tempFolderParent = @"/tmp/"; 105 | 106 | NSString* testFolderName = [NSString stringWithFormat:@"%@-%@", NSStringFromClass([self class]), [self uniqueIdentifierString]]; 107 | NSString* testFileStoragePath = [tempFolderParent stringByAppendingPathComponent:testFolderName]; 108 | [self simpleCreateDirectoryAtPath:testFileStoragePath]; 109 | mTemporaryFolder = [testFileStoragePath retain]; 110 | } 111 | 112 | return mTemporaryFolder; 113 | } 114 | 115 | - (NSString*) pathForTestInputs 116 | { 117 | return [[[NSBundle bundleForClass:[self class]] resourcePath] stringByAppendingPathComponent:@"TestInputs"]; 118 | } 119 | 120 | - (NSString*) pathForTestInputFilename:(NSString*)filename 121 | { 122 | NSString* thePath = [[self pathForTestInputs] stringByAppendingPathComponent:filename]; 123 | STAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:thePath], @"Should have an expected test input file."); 124 | return thePath; 125 | } 126 | 127 | - (NSString*) stringFromTestInputFilename:(NSString*)filename 128 | { 129 | return [NSString stringWithContentsOfFile:[self pathForTestInputFilename:filename] encoding:NSUTF8StringEncoding error:nil]; 130 | } 131 | 132 | - (NSData*) dataFromTestInputFilename:(NSString*)filename 133 | { 134 | NSData* testData = [NSData dataWithContentsOfFile:[self pathForTestInputFilename:filename]]; 135 | STAssertNotNil(testData, @"Should have vaild data from expected test input file."); 136 | return testData; 137 | } 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /Framework/RSTestingKit-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.red-sweater.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | FMWK 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Framework/RSTestingKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // RSTestingKit.h 3 | // RSCommonLib 4 | // 5 | // Created by daniel on 8/21/09. 6 | // Copyright 2009 Red Sweater Software. All rights reserved. 7 | // 8 | // You are granted the right to copy and use this code under the MIT license. See License.txt for more. 9 | // 10 | 11 | #import 12 | 13 | #import 14 | 15 | #import 16 | #import 17 | #import 18 | -------------------------------------------------------------------------------- /Framework/RSTestingKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6532FDAF127DF20900227DF8 /* RSTestingKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6532FDA2127DF20900227DF8 /* RSTestingKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 6532FDB0127DF20900227DF8 /* RSTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 6532FDA3127DF20900227DF8 /* RSTestCase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | 6532FDB1127DF20900227DF8 /* RSTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 6532FDA4127DF20900227DF8 /* RSTestCase.m */; }; 13 | 6532FDB2127DF20900227DF8 /* RSRunLoopWaitingTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 6532FDA5127DF20900227DF8 /* RSRunLoopWaitingTestCase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | 6532FDB3127DF20900227DF8 /* RSRunLoopWaitingTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 6532FDA6127DF20900227DF8 /* RSRunLoopWaitingTestCase.m */; }; 15 | 6532FDB4127DF20900227DF8 /* RSHTTPClientTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 6532FDA8127DF20900227DF8 /* RSHTTPClientTestCase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | 6532FDB5127DF20900227DF8 /* RSHTTPClientTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 6532FDA9127DF20900227DF8 /* RSHTTPClientTestCase.m */; }; 17 | 6532FDB6127DF20900227DF8 /* GTMGarbageCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 6532FDAA127DF20900227DF8 /* GTMGarbageCollection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18 | 6532FDB7127DF20900227DF8 /* GTMDebugSelectorValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 6532FDAB127DF20900227DF8 /* GTMDebugSelectorValidation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | 6532FDB8127DF20900227DF8 /* GTMDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 6532FDAC127DF20900227DF8 /* GTMDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; 20 | 6532FDB9127DF20900227DF8 /* GTMHTTPServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 6532FDAD127DF20900227DF8 /* GTMHTTPServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | 6532FDBA127DF20900227DF8 /* GTMHTTPServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6532FDAE127DF20900227DF8 /* GTMHTTPServer.m */; }; 22 | 6532FDC4127DF27000227DF8 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6532FDC3127DF27000227DF8 /* SenTestingKit.framework */; }; 23 | 6532FE21127DF6E900227DF8 /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6532FE20127DF6E900227DF8 /* License.txt */; }; 24 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 25 | 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 30 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 31 | 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 32 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 33 | 32DBCF5E0370ADEE00C91783 /* RSTestingKit_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSTestingKit_Prefix.pch; sourceTree = ""; }; 34 | 6532FDA2127DF20900227DF8 /* RSTestingKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSTestingKit.h; sourceTree = ""; }; 35 | 6532FDA3127DF20900227DF8 /* RSTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSTestCase.h; sourceTree = ""; }; 36 | 6532FDA4127DF20900227DF8 /* RSTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSTestCase.m; sourceTree = ""; }; 37 | 6532FDA5127DF20900227DF8 /* RSRunLoopWaitingTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSRunLoopWaitingTestCase.h; sourceTree = ""; }; 38 | 6532FDA6127DF20900227DF8 /* RSRunLoopWaitingTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSRunLoopWaitingTestCase.m; sourceTree = ""; }; 39 | 6532FDA8127DF20900227DF8 /* RSHTTPClientTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSHTTPClientTestCase.h; sourceTree = ""; }; 40 | 6532FDA9127DF20900227DF8 /* RSHTTPClientTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSHTTPClientTestCase.m; sourceTree = ""; }; 41 | 6532FDAA127DF20900227DF8 /* GTMGarbageCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMGarbageCollection.h; sourceTree = ""; }; 42 | 6532FDAB127DF20900227DF8 /* GTMDebugSelectorValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDebugSelectorValidation.h; sourceTree = ""; }; 43 | 6532FDAC127DF20900227DF8 /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = ""; }; 44 | 6532FDAD127DF20900227DF8 /* GTMHTTPServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMHTTPServer.h; sourceTree = ""; }; 45 | 6532FDAE127DF20900227DF8 /* GTMHTTPServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMHTTPServer.m; sourceTree = ""; }; 46 | 6532FDC3127DF27000227DF8 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; 47 | 6532FE20127DF6E900227DF8 /* License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = License.txt; path = ../License.txt; sourceTree = ""; }; 48 | 8DC2EF5A0486A6940098B216 /* RSTestingKit-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "RSTestingKit-Info.plist"; sourceTree = ""; }; 49 | 8DC2EF5B0486A6940098B216 /* RSTestingKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RSTestingKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 51 | /* End PBXFileReference section */ 52 | 53 | /* Begin PBXFrameworksBuildPhase section */ 54 | 8DC2EF560486A6940098B216 /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */, 59 | 6532FDC4127DF27000227DF8 /* SenTestingKit.framework in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | 034768DFFF38A50411DB9C8B /* Products */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 8DC2EF5B0486A6940098B216 /* RSTestingKit.framework */, 70 | ); 71 | name = Products; 72 | sourceTree = ""; 73 | }; 74 | 0867D691FE84028FC02AAC07 /* RSTestingKit */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 6532FE20127DF6E900227DF8 /* License.txt */, 78 | 32DBCF5E0370ADEE00C91783 /* RSTestingKit_Prefix.pch */, 79 | 6532FDA1127DF20900227DF8 /* RSTestingKit */, 80 | 089C1665FE841158C02AAC07 /* Resources */, 81 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 82 | 034768DFFF38A50411DB9C8B /* Products */, 83 | ); 84 | name = RSTestingKit; 85 | sourceTree = ""; 86 | }; 87 | 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 91 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, 92 | ); 93 | name = "External Frameworks and Libraries"; 94 | sourceTree = ""; 95 | }; 96 | 089C1665FE841158C02AAC07 /* Resources */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 8DC2EF5A0486A6940098B216 /* RSTestingKit-Info.plist */, 100 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */, 101 | ); 102 | name = Resources; 103 | sourceTree = ""; 104 | }; 105 | 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, 109 | 6532FDC3127DF27000227DF8 /* SenTestingKit.framework */, 110 | ); 111 | name = "Linked Frameworks"; 112 | sourceTree = ""; 113 | }; 114 | 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 0867D6A5FE840307C02AAC07 /* AppKit.framework */, 118 | D2F7E79907B2D74100F64583 /* CoreData.framework */, 119 | 0867D69BFE84028FC02AAC07 /* Foundation.framework */, 120 | ); 121 | name = "Other Frameworks"; 122 | sourceTree = ""; 123 | }; 124 | 6532FDA1127DF20900227DF8 /* RSTestingKit */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 6532FDA2127DF20900227DF8 /* RSTestingKit.h */, 128 | 6532FDA3127DF20900227DF8 /* RSTestCase.h */, 129 | 6532FDA4127DF20900227DF8 /* RSTestCase.m */, 130 | 6532FDA5127DF20900227DF8 /* RSRunLoopWaitingTestCase.h */, 131 | 6532FDA6127DF20900227DF8 /* RSRunLoopWaitingTestCase.m */, 132 | 6532FDA7127DF20900227DF8 /* RSHTTPClientTestCase */, 133 | ); 134 | name = RSTestingKit; 135 | sourceTree = ""; 136 | }; 137 | 6532FDA7127DF20900227DF8 /* RSHTTPClientTestCase */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 6532FDA8127DF20900227DF8 /* RSHTTPClientTestCase.h */, 141 | 6532FDA9127DF20900227DF8 /* RSHTTPClientTestCase.m */, 142 | 6532FDAA127DF20900227DF8 /* GTMGarbageCollection.h */, 143 | 6532FDAB127DF20900227DF8 /* GTMDebugSelectorValidation.h */, 144 | 6532FDAC127DF20900227DF8 /* GTMDefines.h */, 145 | 6532FDAD127DF20900227DF8 /* GTMHTTPServer.h */, 146 | 6532FDAE127DF20900227DF8 /* GTMHTTPServer.m */, 147 | ); 148 | path = RSHTTPClientTestCase; 149 | sourceTree = ""; 150 | }; 151 | /* End PBXGroup section */ 152 | 153 | /* Begin PBXHeadersBuildPhase section */ 154 | 8DC2EF500486A6940098B216 /* Headers */ = { 155 | isa = PBXHeadersBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | 6532FDAF127DF20900227DF8 /* RSTestingKit.h in Headers */, 159 | 6532FDB0127DF20900227DF8 /* RSTestCase.h in Headers */, 160 | 6532FDB2127DF20900227DF8 /* RSRunLoopWaitingTestCase.h in Headers */, 161 | 6532FDB4127DF20900227DF8 /* RSHTTPClientTestCase.h in Headers */, 162 | 6532FDB6127DF20900227DF8 /* GTMGarbageCollection.h in Headers */, 163 | 6532FDB7127DF20900227DF8 /* GTMDebugSelectorValidation.h in Headers */, 164 | 6532FDB8127DF20900227DF8 /* GTMDefines.h in Headers */, 165 | 6532FDB9127DF20900227DF8 /* GTMHTTPServer.h in Headers */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXHeadersBuildPhase section */ 170 | 171 | /* Begin PBXNativeTarget section */ 172 | 8DC2EF4F0486A6940098B216 /* RSTestingKit */ = { 173 | isa = PBXNativeTarget; 174 | buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "RSTestingKit" */; 175 | buildPhases = ( 176 | 8DC2EF500486A6940098B216 /* Headers */, 177 | 8DC2EF520486A6940098B216 /* Resources */, 178 | 8DC2EF540486A6940098B216 /* Sources */, 179 | 8DC2EF560486A6940098B216 /* Frameworks */, 180 | ); 181 | buildRules = ( 182 | ); 183 | dependencies = ( 184 | ); 185 | name = RSTestingKit; 186 | productInstallPath = "$(HOME)/Library/Frameworks"; 187 | productName = RSTestingKit; 188 | productReference = 8DC2EF5B0486A6940098B216 /* RSTestingKit.framework */; 189 | productType = "com.apple.product-type.framework"; 190 | }; 191 | /* End PBXNativeTarget section */ 192 | 193 | /* Begin PBXProject section */ 194 | 0867D690FE84028FC02AAC07 /* Project object */ = { 195 | isa = PBXProject; 196 | buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "RSTestingKit" */; 197 | compatibilityVersion = "Xcode 3.1"; 198 | developmentRegion = English; 199 | hasScannedForEncodings = 1; 200 | knownRegions = ( 201 | English, 202 | Japanese, 203 | French, 204 | German, 205 | ); 206 | mainGroup = 0867D691FE84028FC02AAC07 /* RSTestingKit */; 207 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 208 | projectDirPath = ""; 209 | projectRoot = ""; 210 | targets = ( 211 | 8DC2EF4F0486A6940098B216 /* RSTestingKit */, 212 | ); 213 | }; 214 | /* End PBXProject section */ 215 | 216 | /* Begin PBXResourcesBuildPhase section */ 217 | 8DC2EF520486A6940098B216 /* Resources */ = { 218 | isa = PBXResourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */, 222 | 6532FE21127DF6E900227DF8 /* License.txt in Resources */, 223 | ); 224 | runOnlyForDeploymentPostprocessing = 0; 225 | }; 226 | /* End PBXResourcesBuildPhase section */ 227 | 228 | /* Begin PBXSourcesBuildPhase section */ 229 | 8DC2EF540486A6940098B216 /* Sources */ = { 230 | isa = PBXSourcesBuildPhase; 231 | buildActionMask = 2147483647; 232 | files = ( 233 | 6532FDB1127DF20900227DF8 /* RSTestCase.m in Sources */, 234 | 6532FDB3127DF20900227DF8 /* RSRunLoopWaitingTestCase.m in Sources */, 235 | 6532FDB5127DF20900227DF8 /* RSHTTPClientTestCase.m in Sources */, 236 | 6532FDBA127DF20900227DF8 /* GTMHTTPServer.m in Sources */, 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | }; 240 | /* End PBXSourcesBuildPhase section */ 241 | 242 | /* Begin PBXVariantGroup section */ 243 | 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { 244 | isa = PBXVariantGroup; 245 | children = ( 246 | 089C1667FE841158C02AAC07 /* English */, 247 | ); 248 | name = InfoPlist.strings; 249 | sourceTree = ""; 250 | }; 251 | /* End PBXVariantGroup section */ 252 | 253 | /* Begin XCBuildConfiguration section */ 254 | 1DEB91AE08733DA50010E9CD /* Debug */ = { 255 | isa = XCBuildConfiguration; 256 | buildSettings = { 257 | ALWAYS_SEARCH_USER_PATHS = NO; 258 | COPY_PHASE_STRIP = NO; 259 | DYLIB_COMPATIBILITY_VERSION = 1; 260 | DYLIB_CURRENT_VERSION = 1; 261 | FRAMEWORK_SEARCH_PATHS = ( 262 | "$(inherited)", 263 | "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", 264 | ); 265 | FRAMEWORK_VERSION = A; 266 | GCC_DYNAMIC_NO_PIC = NO; 267 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 268 | GCC_MODEL_TUNING = G5; 269 | GCC_OPTIMIZATION_LEVEL = 0; 270 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 271 | GCC_PREFIX_HEADER = RSTestingKit_Prefix.pch; 272 | INFOPLIST_FILE = "RSTestingKit-Info.plist"; 273 | INSTALL_PATH = "$(HOME)/Library/Frameworks"; 274 | PRODUCT_NAME = RSTestingKit; 275 | WRAPPER_EXTENSION = framework; 276 | }; 277 | name = Debug; 278 | }; 279 | 1DEB91AF08733DA50010E9CD /* Release */ = { 280 | isa = XCBuildConfiguration; 281 | buildSettings = { 282 | ALWAYS_SEARCH_USER_PATHS = NO; 283 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 284 | DYLIB_COMPATIBILITY_VERSION = 1; 285 | DYLIB_CURRENT_VERSION = 1; 286 | FRAMEWORK_SEARCH_PATHS = ( 287 | "$(inherited)", 288 | "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", 289 | ); 290 | FRAMEWORK_VERSION = A; 291 | GCC_MODEL_TUNING = G5; 292 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 293 | GCC_PREFIX_HEADER = RSTestingKit_Prefix.pch; 294 | INFOPLIST_FILE = "RSTestingKit-Info.plist"; 295 | INSTALL_PATH = "$(HOME)/Library/Frameworks"; 296 | PRODUCT_NAME = RSTestingKit; 297 | WRAPPER_EXTENSION = framework; 298 | }; 299 | name = Release; 300 | }; 301 | 1DEB91B208733DA50010E9CD /* Debug */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 305 | GCC_C_LANGUAGE_STANDARD = gnu99; 306 | GCC_OPTIMIZATION_LEVEL = 0; 307 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 308 | GCC_WARN_UNUSED_VARIABLE = YES; 309 | ONLY_ACTIVE_ARCH = YES; 310 | PREBINDING = NO; 311 | SDKROOT = macosx10.6; 312 | }; 313 | name = Debug; 314 | }; 315 | 1DEB91B308733DA50010E9CD /* Release */ = { 316 | isa = XCBuildConfiguration; 317 | buildSettings = { 318 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 319 | GCC_C_LANGUAGE_STANDARD = gnu99; 320 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 321 | GCC_WARN_UNUSED_VARIABLE = YES; 322 | PREBINDING = NO; 323 | SDKROOT = macosx10.6; 324 | }; 325 | name = Release; 326 | }; 327 | /* End XCBuildConfiguration section */ 328 | 329 | /* Begin XCConfigurationList section */ 330 | 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "RSTestingKit" */ = { 331 | isa = XCConfigurationList; 332 | buildConfigurations = ( 333 | 1DEB91AE08733DA50010E9CD /* Debug */, 334 | 1DEB91AF08733DA50010E9CD /* Release */, 335 | ); 336 | defaultConfigurationIsVisible = 0; 337 | defaultConfigurationName = Release; 338 | }; 339 | 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "RSTestingKit" */ = { 340 | isa = XCConfigurationList; 341 | buildConfigurations = ( 342 | 1DEB91B208733DA50010E9CD /* Debug */, 343 | 1DEB91B308733DA50010E9CD /* Release */, 344 | ); 345 | defaultConfigurationIsVisible = 0; 346 | defaultConfigurationName = Release; 347 | }; 348 | /* End XCConfigurationList section */ 349 | }; 350 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 351 | } 352 | -------------------------------------------------------------------------------- /Framework/RSTestingKit_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'RSTestingKit' target in the 'RSTestingKit' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | 2 | The code in this project is licensed separately under the Apache and MIT licenses: 3 | 4 | All files in this project that have a GTM prefix are licensed by Google 5 | the terms of the Apache license. See comments in header of each source file for more information. 6 | 7 | All other files in this project are Copyright © Red Sweater Software and licensed to you 8 | under terms of the MIT license: 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## RSTestingKit ## 2 | 3 | Sorry for the lack of proper documentation. For some perspective on the usage of these classes, please have a [look at the slides](http://www.red-sweater.com/talks/UnitTesting.pdf) for a talk I gave on the subject. 4 | 5 | 6 | 7 | 8 | --------------------------------------------------------------------------------