Skip to content
Browse files

Merge commit '3b73277db6b6a74bc88aa594d9847cadeaa07974' as 'External/…

…RXSynchronously'
  • Loading branch information...
2 parents 1b60406 + 3b73277 commit 84fcd6f31664af75fe49635f08419c506017dcd3 @robrix committed Nov 27, 2011
View
5 External/RXSynchronously/.gitignore
@@ -0,0 +1,5 @@
+.DS_Store
+xcuserdata
+*.mode*
+*.pbxuser
+*.xcuserdatad
View
7 External/RXSynchronously/LICENSE
@@ -0,0 +1,7 @@
+Copyright (c) 2011 Rob Rix
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
29 External/RXSynchronously/README.mdown
@@ -0,0 +1,29 @@
+#RXSynchronously
+
+A convenient way to synchronize the calling thread on some asynchronous work.
+
+ // 1
+ RXSynchronously(^(RXSynchronousCompletionBlock didComplete) {
+ // 2
+ [worker doAsynchronousWorkWithCompletionHandler:^{
+ // 3
+ didComplete();
+ }];
+ });
+ // 4
+
+Control flow is, as you would expect, effectively serial:
+
+1. Control enters.
+2. Some asynchronous work is begun.
+3. The asynchronous work completes, at which point we call the `didComplete` block that RXSynchronously passed us.
+4. The calling thread resumes.
+
+#Use cases
+
+I use this widely when unit testing asynchronous code, with basically the same pattern as in the example above. OCUnit tests are necessarily synchronous, so `RXSynchronously` is an excellent way to button things down.
+
+#Gotchas
+
+- As with any attempt to block until some signal is received, you should beware of deadlocks. `RXSynchronouslyWithTimeout` may be more appropriate in some cases. This is especially likely when unit testing asynchronous code that executes on the main queue with OCUnit, as OCUnit executes on the main thread (where the main queue is dispatched).
+- Absolutely do not forget to call the `didComplete` block.
View
410 External/RXSynchronously/RXSynchronously.xcodeproj/project.pbxproj
@@ -0,0 +1,410 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ D4FCDC6B14830AD200EB9EF7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4FCDC6A14830AD200EB9EF7 /* Cocoa.framework */; };
+ D4FCDC7514830AD300EB9EF7 /* RXSynchronously.m in Sources */ = {isa = PBXBuildFile; fileRef = D4FCDC7414830AD300EB9EF7 /* RXSynchronously.m */; };
+ D4FCDC7D14830AD300EB9EF7 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4FCDC7C14830AD300EB9EF7 /* SenTestingKit.framework */; };
+ D4FCDC7E14830AD300EB9EF7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4FCDC6A14830AD200EB9EF7 /* Cocoa.framework */; };
+ D4FCDC8114830AD300EB9EF7 /* libRXSynchronously.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4FCDC6714830AD200EB9EF7 /* libRXSynchronously.a */; };
+ D4FCDC8714830AD300EB9EF7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4FCDC8514830AD300EB9EF7 /* InfoPlist.strings */; };
+ D4FCDC8A14830AD300EB9EF7 /* RXSynchronouslyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4FCDC8914830AD300EB9EF7 /* RXSynchronouslyTests.m */; };
+ D4FCDC9514830BBC00EB9EF7 /* RXAssertions.m in Sources */ = {isa = PBXBuildFile; fileRef = D4FCDC9414830BBC00EB9EF7 /* RXAssertions.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ D4FCDC7F14830AD300EB9EF7 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = D4FCDC5E14830AD200EB9EF7 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = D4FCDC6614830AD200EB9EF7;
+ remoteInfo = RXSynchronously;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ D4FCDC6714830AD200EB9EF7 /* libRXSynchronously.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRXSynchronously.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ D4FCDC6A14830AD200EB9EF7 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+ D4FCDC6D14830AD200EB9EF7 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
+ D4FCDC6E14830AD200EB9EF7 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
+ D4FCDC6F14830AD200EB9EF7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ D4FCDC7214830AD200EB9EF7 /* RXSynchronously-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RXSynchronously-Prefix.pch"; sourceTree = "<group>"; };
+ D4FCDC7314830AD300EB9EF7 /* RXSynchronously.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RXSynchronously.h; sourceTree = "<group>"; };
+ D4FCDC7414830AD300EB9EF7 /* RXSynchronously.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RXSynchronously.m; sourceTree = "<group>"; };
+ D4FCDC7B14830AD300EB9EF7 /* RXSynchronouslyTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RXSynchronouslyTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
+ D4FCDC7C14830AD300EB9EF7 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
+ D4FCDC8414830AD300EB9EF7 /* RXSynchronouslyTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RXSynchronouslyTests-Info.plist"; sourceTree = "<group>"; };
+ D4FCDC8614830AD300EB9EF7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ D4FCDC8914830AD300EB9EF7 /* RXSynchronouslyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RXSynchronouslyTests.m; sourceTree = "<group>"; };
+ D4FCDC9314830BBC00EB9EF7 /* RXAssertions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RXAssertions.h; sourceTree = "<group>"; };
+ D4FCDC9414830BBC00EB9EF7 /* RXAssertions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RXAssertions.m; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D4FCDC6414830AD200EB9EF7 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D4FCDC6B14830AD200EB9EF7 /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D4FCDC7714830AD300EB9EF7 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D4FCDC7D14830AD300EB9EF7 /* SenTestingKit.framework in Frameworks */,
+ D4FCDC7E14830AD300EB9EF7 /* Cocoa.framework in Frameworks */,
+ D4FCDC8114830AD300EB9EF7 /* libRXSynchronously.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ D4FCDC5C14830AD200EB9EF7 = {
+ isa = PBXGroup;
+ children = (
+ D4FCDC7014830AD200EB9EF7 /* RXSynchronously */,
+ D4FCDC8214830AD300EB9EF7 /* RXSynchronouslyTests */,
+ D4FCDC6914830AD200EB9EF7 /* Frameworks */,
+ D4FCDC6814830AD200EB9EF7 /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ D4FCDC6814830AD200EB9EF7 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D4FCDC6714830AD200EB9EF7 /* libRXSynchronously.a */,
+ D4FCDC7B14830AD300EB9EF7 /* RXSynchronouslyTests.octest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ D4FCDC6914830AD200EB9EF7 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ D4FCDC6A14830AD200EB9EF7 /* Cocoa.framework */,
+ D4FCDC7C14830AD300EB9EF7 /* SenTestingKit.framework */,
+ D4FCDC6C14830AD200EB9EF7 /* Other Frameworks */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ D4FCDC6C14830AD200EB9EF7 /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ D4FCDC6D14830AD200EB9EF7 /* AppKit.framework */,
+ D4FCDC6E14830AD200EB9EF7 /* CoreData.framework */,
+ D4FCDC6F14830AD200EB9EF7 /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ D4FCDC7014830AD200EB9EF7 /* RXSynchronously */ = {
+ isa = PBXGroup;
+ children = (
+ D4FCDC7314830AD300EB9EF7 /* RXSynchronously.h */,
+ D4FCDC7414830AD300EB9EF7 /* RXSynchronously.m */,
+ D4FCDC7114830AD200EB9EF7 /* Supporting Files */,
+ );
+ path = RXSynchronously;
+ sourceTree = "<group>";
+ };
+ D4FCDC7114830AD200EB9EF7 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ D4FCDC7214830AD200EB9EF7 /* RXSynchronously-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ D4FCDC8214830AD300EB9EF7 /* RXSynchronouslyTests */ = {
+ isa = PBXGroup;
+ children = (
+ D4FCDC9314830BBC00EB9EF7 /* RXAssertions.h */,
+ D4FCDC9414830BBC00EB9EF7 /* RXAssertions.m */,
+ D4FCDC8914830AD300EB9EF7 /* RXSynchronouslyTests.m */,
+ D4FCDC8314830AD300EB9EF7 /* Supporting Files */,
+ );
+ path = RXSynchronouslyTests;
+ sourceTree = "<group>";
+ };
+ D4FCDC8314830AD300EB9EF7 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ D4FCDC8414830AD300EB9EF7 /* RXSynchronouslyTests-Info.plist */,
+ D4FCDC8514830AD300EB9EF7 /* InfoPlist.strings */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ D4FCDC6514830AD200EB9EF7 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ D4FCDC6614830AD200EB9EF7 /* RXSynchronously */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D4FCDC8D14830AD300EB9EF7 /* Build configuration list for PBXNativeTarget "RXSynchronously" */;
+ buildPhases = (
+ D4FCDC6314830AD200EB9EF7 /* Sources */,
+ D4FCDC6414830AD200EB9EF7 /* Frameworks */,
+ D4FCDC6514830AD200EB9EF7 /* Headers */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = RXSynchronously;
+ productName = RXSynchronously;
+ productReference = D4FCDC6714830AD200EB9EF7 /* libRXSynchronously.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+ D4FCDC7A14830AD300EB9EF7 /* RXSynchronouslyTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D4FCDC9014830AD300EB9EF7 /* Build configuration list for PBXNativeTarget "RXSynchronouslyTests" */;
+ buildPhases = (
+ D4FCDC7614830AD300EB9EF7 /* Sources */,
+ D4FCDC7714830AD300EB9EF7 /* Frameworks */,
+ D4FCDC7814830AD300EB9EF7 /* Resources */,
+ D4FCDC7914830AD300EB9EF7 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ D4FCDC8014830AD300EB9EF7 /* PBXTargetDependency */,
+ );
+ name = RXSynchronouslyTests;
+ productName = RXSynchronouslyTests;
+ productReference = D4FCDC7B14830AD300EB9EF7 /* RXSynchronouslyTests.octest */;
+ productType = "com.apple.product-type.bundle";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ D4FCDC5E14830AD200EB9EF7 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0420;
+ ORGANIZATIONNAME = "Monochrome Industries";
+ };
+ buildConfigurationList = D4FCDC6114830AD200EB9EF7 /* Build configuration list for PBXProject "RXSynchronously" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = D4FCDC5C14830AD200EB9EF7;
+ productRefGroup = D4FCDC6814830AD200EB9EF7 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D4FCDC6614830AD200EB9EF7 /* RXSynchronously */,
+ D4FCDC7A14830AD300EB9EF7 /* RXSynchronouslyTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ D4FCDC7814830AD300EB9EF7 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D4FCDC8714830AD300EB9EF7 /* InfoPlist.strings in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ D4FCDC7914830AD300EB9EF7 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D4FCDC6314830AD200EB9EF7 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D4FCDC7514830AD300EB9EF7 /* RXSynchronously.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D4FCDC7614830AD300EB9EF7 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D4FCDC8A14830AD300EB9EF7 /* RXSynchronouslyTests.m in Sources */,
+ D4FCDC9514830BBC00EB9EF7 /* RXAssertions.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ D4FCDC8014830AD300EB9EF7 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = D4FCDC6614830AD200EB9EF7 /* RXSynchronously */;
+ targetProxy = D4FCDC7F14830AD300EB9EF7 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ D4FCDC8514830AD300EB9EF7 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ D4FCDC8614830AD300EB9EF7 /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ D4FCDC8B14830AD300EB9EF7 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.6;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ D4FCDC8C14830AD300EB9EF7 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.6;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+ D4FCDC8E14830AD300EB9EF7 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "RXSynchronously/RXSynchronously-Prefix.pch";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ D4FCDC8F14830AD300EB9EF7 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "RXSynchronously/RXSynchronously-Prefix.pch";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+ D4FCDC9114830AD300EB9EF7 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "RXSynchronously/RXSynchronously-Prefix.pch";
+ INFOPLIST_FILE = "RXSynchronouslyTests/RXSynchronouslyTests-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Debug;
+ };
+ D4FCDC9214830AD300EB9EF7 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "RXSynchronously/RXSynchronously-Prefix.pch";
+ INFOPLIST_FILE = "RXSynchronouslyTests/RXSynchronouslyTests-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ D4FCDC6114830AD200EB9EF7 /* Build configuration list for PBXProject "RXSynchronously" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D4FCDC8B14830AD300EB9EF7 /* Debug */,
+ D4FCDC8C14830AD300EB9EF7 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D4FCDC8D14830AD300EB9EF7 /* Build configuration list for PBXNativeTarget "RXSynchronously" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D4FCDC8E14830AD300EB9EF7 /* Debug */,
+ D4FCDC8F14830AD300EB9EF7 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ };
+ D4FCDC9014830AD300EB9EF7 /* Build configuration list for PBXNativeTarget "RXSynchronouslyTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D4FCDC9114830AD300EB9EF7 /* Debug */,
+ D4FCDC9214830AD300EB9EF7 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = D4FCDC5E14830AD200EB9EF7 /* Project object */;
+}
View
7 ...al/RXSynchronously/RXSynchronously.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:RXSynchronously.xcodeproj">
+ </FileRef>
+</Workspace>
View
7 External/RXSynchronously/RXSynchronously/RXSynchronously-Prefix.pch
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'RXSynchronously' target in the 'RXSynchronously' project
+//
+
+#ifdef __OBJC__
+ #import <Cocoa/Cocoa.h>
+#endif
View
29 External/RXSynchronously/RXSynchronously/RXSynchronously.h
@@ -0,0 +1,29 @@
+// RXSynchronously.h
+// Created by Rob Rix on 11-11-27.
+// Copyright (c) 2011 Monochrome Industries. All rights reserved.
+
+#import <Foundation/Foundation.h>
+
+typedef void (^RXSynchronousCompletionBlock)();
+typedef void (^RXSynchronousBlock)(RXSynchronousCompletionBlock);
+
+/*
+Synchronizes the calling thread with the asynchronous work you do in the block you pass to it.
+
+Like so:
+
+ RXSynchronously(^(RXSynchronousCompletionBlock didComplete) {
+ [worker doSomeAsynchronousWorkWithCompletionHandler:^{
+ // clean up, notify, etc
+ didComplete(); // call the didComplete block you received to conclude waiting
+ }];
+ });
+ // continue on, safe in the knowledge that the asynchronous work has completed
+
+RXSynchronously will block until didComplete() is called.
+
+Its impatient sibling, RXSynchronouslyWithTimeout, lets you time out on the wait. Using DISPATCH_TIME_NOW as the timeout is a quick and easy way to test if the work you’re doing is actually performed synchronously or asynchronously (but beware a race condition—fast asynchronous work could complete before RXSynchronouslyWithTimeout returns).
+*/
+
+void RXSynchronously(RXSynchronousBlock block); // never times out
+void RXSynchronouslyWithTimeout(dispatch_time_t timeout, RXSynchronousBlock block);
View
20 External/RXSynchronously/RXSynchronously/RXSynchronously.m
@@ -0,0 +1,20 @@
+// RXSynchronously.m
+// Created by Rob Rix on 11-11-27.
+// Copyright (c) 2011 Monochrome Industries. All rights reserved.
+
+#import "RXSynchronously.h"
+
+void RXSynchronously(RXSynchronousBlock block) {
+ RXSynchronouslyWithTimeout(DISPATCH_TIME_FOREVER, block);
+}
+
+void RXSynchronouslyWithTimeout(dispatch_time_t timeout, RXSynchronousBlock block) {
+ dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+
+ block(^{
+ dispatch_semaphore_signal(semaphore);
+ });
+
+ dispatch_semaphore_wait(semaphore, timeout);
+ dispatch_release(semaphore);
+}
View
82 External/RXSynchronously/RXSynchronouslyTests/RXAssertions.h
@@ -0,0 +1,82 @@
+// RXAssertions.h
+// Created by Rob Rix on 2009-08-20
+// Copyright 2009 Decimus Software, Inc.
+
+#import <SenTestingKit/SenTestingKit.h>
+
+// Assertion macros that don’t require you to describe the assertion. Perfect for use with intention-revealing code.
+
+// Don’t use this unless you’re writing your own assertions. The first argument is ignored, so the assertions can have optional messages appended to them without suffering a compiler error.
+#define RXOptionalMessageString(ignored, format, ...) [NSString stringWithFormat: (format), ## __VA_ARGS__]
+
+#define RXAssert(_expression, ...) do {\
+ __typeof__(_expression) __condition = (_expression);\
+ if(!__condition)\
+ STFail(RXOptionalMessageString(, ## __VA_ARGS__, @"%s was unexpectedly false.", #_expression));\
+} while(0)
+#define RXAssertFalse(_expression, ...) do {\
+ __typeof__(_expression) __condition = (_expression);\
+ if(__condition)\
+ STFail(RXOptionalMessageString(, ## __VA_ARGS__, @"%s was unexpectedly true.", #_expression));\
+} while(0)
+
+// casts the expected value to the type of the actual value. will fail (and rightly so) if you try crazy casts like struct to pointer.
+#define RXAssertEquals(_actual, _expected, ...) do {\
+ __typeof__(_actual) __actual = (_actual), __expected = (__typeof__(__actual))(_expected);\
+ if(![RXAssertionHelper compareValue: &__actual withValue: &__expected ofObjCType: @encode(__typeof__(__actual))]) {\
+ STFail(@"%s has value %@, not expected value %@. %@", #_actual, [RXAssertionHelper descriptionForValue: &__actual ofObjCType: @encode(__typeof__(__actual))], [RXAssertionHelper descriptionForValue: &__expected ofObjCType: @encode(__typeof__(__actual))], RXOptionalMessageString(, ## __VA_ARGS__, @""));\
+ }\
+} while(0)
+#define RXAssertNotEquals(_actual, _expected, ...) do {\
+ __typeof__(_actual) __actual = (_actual), __expected = (__typeof__(__actual))(_expected);\
+ if([RXAssertionHelper compareValue: &__actual withValue: &__expected ofObjCType: @encode(__typeof__(__actual))]) {\
+ STFail(@"%s has unexpected value %@. %@", #_actual, [RXAssertionHelper descriptionForValue: &__actual ofObjCType: @encode(__typeof__(__actual))], RXOptionalMessageString(, ## __VA_ARGS__, @""));\
+ }\
+} while(0)
+
+#define RXAssertNil(_thing, ...) do {\
+ __typeof__(_thing) __thing = (_thing);\
+ if(__thing != nil) STFail(RXOptionalMessageString(, ## __VA_ARGS__, @"%s was unexpectedly %@, not nil.", #_thing, __thing));\
+} while(0)
+#define RXAssertNotNil(_thing, ...) do {\
+ if((_thing) == nil) STFail(RXOptionalMessageString(, ## __VA_ARGS__, @"%s was unexpectedly nil.", #_thing));\
+} while(0)
+
+
+//#ifdef __clang__
+#if 0
+ // this is bad, as strict aliasing will break it, but clang doesn’t handle union casts correctly
+ #define RXCast(x, toType) *(toType *)&(x)
+#else
+ #define RXCast(x, toType) (((union{__typeof__(x) a; toType b;})x).b)
+#endif
+#define RXRound(value, place) (round((value) / (place)) * (place))
+
+
+typedef BOOL (*RXAssertionHelperComparisonFunction)(const void *aRef, const void *bRef);
+typedef NSString *(*RXAssertionHelperDescriptionFunction)(const void *ref);
+
+
+// making these functions available for registering Polymorph types
+BOOL RXAssertionHelperObjectComparison(const void *a, const void *b);
+NSString *RXAssertionHelperObjectDescription(const void *ref);
+
+BOOL RXAssertionHelperCFTypeRefComparison(const void *a, const void *b);
+NSString *RXAssertionHelperCFTypeRefDescription(const void *ref);
+
+
+@interface RXAssertionHelper : NSObject
+
++(void)registerComparisonFunction:(RXAssertionHelperComparisonFunction)comparator forObjCType:(const char *)type;
++(BOOL)compareValue:(const void *)aRef withValue:(const void *)bRef ofObjCType:(const char *)type;
+
++(void)registerDescriptionFunction:(RXAssertionHelperDescriptionFunction)descriptor forObjCType:(const char *)type;
++(NSString *)descriptionForValue:(const void *)ref ofObjCType:(const char *)type;
+
++(double)floatingPointComparisonAccuracy;
++(void)setFloatingPointComparisonAccuracy:(double)epsilon;
+
+// returns a nicely formatted name for the test case selector
++(NSString *)humanReadableNameForTestCaseSelector:(SEL)selector;
+
+@end
View
293 External/RXSynchronously/RXSynchronouslyTests/RXAssertions.m
@@ -0,0 +1,293 @@
+// RXAssertions.m
+// Created by Rob Rix on 2009-08-20
+// Copyright 2009 Decimus Software, Inc.
+
+#import <math.h>
+#import "RXAssertions.h"
+
+static NSMutableDictionary *RXAssertionHelperComparisonFunctions = nil;
+static NSMutableDictionary *RXAssertionHelperDescriptionFunctions = nil;
+
+static double RXAssertionHelperFloatingPointComparisonAccuracy = 0.0;
+
+BOOL RXAssertionHelperInt8Comparison(const void *a, const void *b);
+BOOL RXAssertionHelperInt16Comparison(const void *a, const void *b);
+BOOL RXAssertionHelperInt32Comparison(const void *a, const void *b);
+BOOL RXAssertionHelperInt64Comparison(const void *a, const void *b);
+BOOL RXAssertionHelperFloatComparison(const void *a, const void *b);
+BOOL RXAssertionHelperDoubleComparison(const void *a, const void *b);
+BOOL RXAssertionHelperObjectComparison(const void *a, const void *b);
+BOOL RXAssertionHelperCFTypeRefComparison(const void *a, const void *b);
+BOOL RXAssertionHelperNSPointComparison(const void *a, const void *b);
+BOOL RXAssertionHelperNSRangeComparison(const void *a, const void *b);
+
+NSString *RXAssertionHelperHexadecimalDescription(const void *ref);
+NSString *RXAssertionHelperInt8Description(const void *ref);
+NSString *RXAssertionHelperUInt8Description(const void *ref);
+NSString *RXAssertionHelperInt16Description(const void *ref);
+NSString *RXAssertionHelperUInt16Description(const void *ref);
+NSString *RXAssertionHelperInt32Description(const void *ref);
+NSString *RXAssertionHelperUInt32Description(const void *ref);
+NSString *RXAssertionHelperInt64Description(const void *ref);
+NSString *RXAssertionHelperUInt64Description(const void *ref);
+NSString *RXAssertionHelperFloatDescription(const void *ref);
+NSString *RXAssertionHelperDoubleDescription(const void *ref);
+NSString *RXAssertionHelperObjectDescription(const void *ref);
+NSString *RXAssertionHelperNSPointDescription(const void *ref);
+NSString *RXAssertionHelperNSRangeDescription(const void *ref);
+
+
+BOOL RXAssertionHelperInt8Comparison(const void *a, const void *b) {
+ return (*(RXCast(a, const uint8_t *))) == (*(RXCast(b, const uint8_t *)));
+}
+
+BOOL RXAssertionHelperInt16Comparison(const void *a, const void *b) {
+ return (*(RXCast(a, const uint16_t *))) == (*(RXCast(b, const uint16_t *)));
+}
+
+BOOL RXAssertionHelperInt32Comparison(const void *a, const void *b) {
+ return (*(RXCast(a, const uint32_t *))) == (*(RXCast(b, const uint32_t *)));
+}
+
+BOOL RXAssertionHelperInt64Comparison(const void *a, const void *b) {
+ return (*(RXCast(a, const uint64_t *))) == (*(RXCast(b, const uint64_t *)));
+}
+
+BOOL RXAssertionHelperFloatComparison(const void *a, const void *b) {
+ double _a = *RXCast(a, const float *), _b = *RXCast(b, const float *);
+ return islessequal(MAX(_a, _b) - MIN(_a, _b), RXAssertionHelperFloatingPointComparisonAccuracy);
+}
+
+BOOL RXAssertionHelperDoubleComparison(const void *a, const void *b) {
+ double _a = *RXCast(a, const double *), _b = *RXCast(b, const double *);
+ return islessequal(MAX(_a, _b) - MIN(_a, _b), RXAssertionHelperFloatingPointComparisonAccuracy);
+}
+
+BOOL RXAssertionHelperObjectComparison(const void *a, const void *b) {
+ const id _a = *RXCast(a, const id *), _b = *RXCast(b, const id *);
+ return (_a == _b) || [_a isEqual: _b];
+}
+
+BOOL RXAssertionHelperCFTypeRefComparison(const void *a, const void *b) {
+ CFTypeRef _a = *RXCast(a, CFTypeRef *), _b = *RXCast(b, CFTypeRef *);
+ return
+ (_a == _b)
+ || ((_a != nil) && (_b != nil) && CFEqual(_a, _b));
+}
+
+BOOL RXAssertionHelperNSPointComparison(const void *a, const void *b) {
+ return NSEqualPoints(*RXCast(a, const NSPoint *), *RXCast(b, const NSPoint *));
+}
+
+BOOL RXAssertionHelperNSRangeComparison(const void *a, const void *b) {
+ return NSEqualRanges(*RXCast(a, const NSRange *), *RXCast(b, const NSRange *));
+}
+
+
+NSString *RXAssertionHelperHexadecimalDescription(const void *ref) {
+ return [NSString stringWithFormat: @"%x", *RXCast(ref, const void **)];
+}
+
+NSString *RXAssertionHelperInt8Description(const void *ref) {
+ return [NSString stringWithFormat: @"%d", *RXCast(ref, const int8_t *)];
+}
+
+NSString *RXAssertionHelperUInt8Description(const void *ref) {
+ return [NSString stringWithFormat: @"%u", *RXCast(ref, const uint8_t *)];
+}
+
+NSString *RXAssertionHelperInt16Description(const void *ref) {
+ return [NSString stringWithFormat: @"%d", *RXCast(ref, const int16_t *)];
+}
+
+NSString *RXAssertionHelperUInt16Description(const void *ref) {
+ return [NSString stringWithFormat: @"%u", *RXCast(ref, const uint16_t *)];
+}
+
+NSString *RXAssertionHelperInt32Description(const void *ref) {
+ return [NSString stringWithFormat: @"%d", *RXCast(ref, const int32_t *)];
+}
+
+NSString *RXAssertionHelperUInt32Description(const void *ref) {
+ return [NSString stringWithFormat: @"%u", *RXCast(ref, const uint32_t *)];
+}
+
+NSString *RXAssertionHelperInt64Description(const void *ref) {
+ return [NSString stringWithFormat: @"%qi", *RXCast(ref, const int64_t *)];
+}
+
+NSString *RXAssertionHelperUInt64Description(const void *ref) {
+ return [NSString stringWithFormat: @"%qu", *RXCast(ref, const uint64_t *)];
+}
+
+NSString *RXAssertionHelperFloatDescription(const void *ref) {
+ return [NSString stringWithFormat: @"%f", *RXCast(ref, const float *)];
+}
+
+NSString *RXAssertionHelperDoubleDescription(const void *ref) {
+ return [NSString stringWithFormat: @"%f", *RXCast(ref, const double *)];
+}
+
+NSString *RXAssertionHelperObjectDescription(const void *ref) {
+ return [NSString stringWithFormat: @"%@", *RXCast(ref, const id *)];
+}
+
+//NSString *RXAssertionHelperCFTypeRefDescription(const void *ref) {
+// CFTypeRef _ref = *RXCast(ref, CFTypeRef *);
+// return _ref ? [(__bridge id)_ref description] : @"(null)";
+//}
+
+NSString *RXAssertionHelperNSPointDescription(const void *ref) {
+ return NSStringFromPoint(*RXCast(ref, const NSPoint *));
+}
+
+NSString *RXAssertionHelperNSRangeDescription(const void *ref) {
+ return NSStringFromRange(*RXCast(ref, const NSRange *));
+}
+
+
+@implementation RXAssertionHelper
+
++(void)initialize {
+ if(!RXAssertionHelperComparisonFunctions) {
+ RXAssertionHelperComparisonFunctions = [[NSMutableDictionary alloc] init];
+ }
+ if(!RXAssertionHelperDescriptionFunctions) {
+ RXAssertionHelperDescriptionFunctions = [[NSMutableDictionary alloc] init];
+ }
+
+#ifdef __LP64__
+ [self registerComparisonFunction: RXAssertionHelperInt64Comparison forObjCType: @encode(void *)];
+#else
+ [self registerComparisonFunction: RXAssertionHelperInt32Comparison forObjCType: @encode(void *)];
+#endif
+ [self registerComparisonFunction: RXAssertionHelperInt8Comparison forObjCType: @encode(int8_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt8Comparison forObjCType: @encode(uint8_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt16Comparison forObjCType: @encode(int16_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt16Comparison forObjCType: @encode(uint16_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt32Comparison forObjCType: @encode(int32_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt32Comparison forObjCType: @encode(uint32_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt64Comparison forObjCType: @encode(int64_t)];
+ [self registerComparisonFunction: RXAssertionHelperInt64Comparison forObjCType: @encode(uint64_t)];
+ [self registerComparisonFunction: RXAssertionHelperFloatComparison forObjCType: @encode(float)];
+ [self registerComparisonFunction: RXAssertionHelperDoubleComparison forObjCType: @encode(double)];
+ [self registerComparisonFunction: RXAssertionHelperObjectComparison forObjCType: @encode(id)];
+ [self registerComparisonFunction: RXAssertionHelperObjectComparison forObjCType: @encode(Class)];
+ CFStringRef string = NULL;
+ CFArrayRef array = NULL;
+ CFCharacterSetRef characterSet = NULL;
+ [self registerComparisonFunction: RXAssertionHelperCFTypeRefComparison forObjCType: @encode(__typeof__(string))]; // __typeof__ keeps qualifiers, e.g. const
+ [self registerComparisonFunction: RXAssertionHelperCFTypeRefComparison forObjCType: @encode(__typeof__(array))]; // __typeof__ keeps qualifiers, e.g. const
+ [self registerComparisonFunction: RXAssertionHelperCFTypeRefComparison forObjCType: @encode(__typeof__(characterSet))]; // __typeof__ keeps qualifiers, e.g. const
+ [self registerComparisonFunction: RXAssertionHelperNSPointComparison forObjCType: @encode(NSPoint)];
+ [self registerComparisonFunction: RXAssertionHelperNSPointComparison forObjCType: @encode(CGPoint)];
+ [self registerComparisonFunction: RXAssertionHelperNSRangeComparison forObjCType: @encode(NSRange)];
+
+ [self registerDescriptionFunction: RXAssertionHelperHexadecimalDescription forObjCType: @encode(void *)];
+ [self registerDescriptionFunction: RXAssertionHelperInt8Description forObjCType: @encode(int8_t)];
+ [self registerDescriptionFunction: RXAssertionHelperUInt8Description forObjCType: @encode(uint8_t)];
+ [self registerDescriptionFunction: RXAssertionHelperInt16Description forObjCType: @encode(int16_t)];
+ [self registerDescriptionFunction: RXAssertionHelperUInt16Description forObjCType: @encode(uint16_t)];
+ [self registerDescriptionFunction: RXAssertionHelperInt32Description forObjCType: @encode(int32_t)];
+ [self registerDescriptionFunction: RXAssertionHelperUInt32Description forObjCType: @encode(uint32_t)];
+ [self registerDescriptionFunction: RXAssertionHelperInt64Description forObjCType: @encode(int64_t)];
+ [self registerDescriptionFunction: RXAssertionHelperUInt64Description forObjCType: @encode(uint64_t)];
+ [self registerDescriptionFunction: RXAssertionHelperFloatDescription forObjCType: @encode(float)];
+ [self registerDescriptionFunction: RXAssertionHelperDoubleDescription forObjCType: @encode(double)];
+ [self registerDescriptionFunction: RXAssertionHelperObjectDescription forObjCType: @encode(id)];
+ [self registerDescriptionFunction: RXAssertionHelperObjectDescription forObjCType: @encode(Class)];
+// [self registerDescriptionFunction: RXAssertionHelperCFTypeRefDescription forObjCType: @encode(__typeof__(string))]; // __typeof__ keeps qualifiers, e.g. const
+// [self registerDescriptionFunction: RXAssertionHelperCFTypeRefDescription forObjCType: @encode(__typeof__(array))]; // __typeof__ keeps qualifiers, e.g. const
+// [self registerDescriptionFunction: RXAssertionHelperCFTypeRefDescription forObjCType: @encode(__typeof__(characterSet))]; // __typeof__ keeps qualifiers, e.g. const
+ [self registerDescriptionFunction: RXAssertionHelperNSPointDescription forObjCType: @encode(NSPoint)];
+ [self registerDescriptionFunction: RXAssertionHelperNSPointDescription forObjCType: @encode(CGPoint)];
+ [self registerDescriptionFunction: RXAssertionHelperNSRangeDescription forObjCType: @encode(NSRange)];
+}
+
+
++(NSString *)keyForObjCType:(const char *)type {
+ return [NSString stringWithFormat: @"%s", type];
+}
+
++(RXAssertionHelperComparisonFunction)comparisonFunctionForObjCType:(const char *)type {
+ return [[RXAssertionHelperComparisonFunctions objectForKey: [self keyForObjCType: type]] pointerValue];
+}
+
++(void)registerComparisonFunction:(RXAssertionHelperComparisonFunction)comparator forObjCType:(const char *)type {
+ [RXAssertionHelperComparisonFunctions setObject: [NSValue valueWithPointer: comparator] forKey: [self keyForObjCType: type]];
+}
+
++(BOOL)compareValue:(const void *)aRef withValue:(const void *)bRef ofObjCType:(const char *)type {
+ RXAssertionHelperComparisonFunction function =
+ [self comparisonFunctionForObjCType: type]
+ ?:
+#ifdef __LP64__
+ RXAssertionHelperInt64Comparison;
+#else
+ RXAssertionHelperInt32Comparison;
+#endif
+ return function(aRef, bRef);
+}
+
+
++(RXAssertionHelperDescriptionFunction)descriptionFunctionForObjCType:(const char *)type {
+ return [[RXAssertionHelperDescriptionFunctions objectForKey: [self keyForObjCType: type]] pointerValue];
+}
+
++(void)registerDescriptionFunction:(RXAssertionHelperDescriptionFunction)descriptor forObjCType:(const char *)type {
+ [RXAssertionHelperDescriptionFunctions setObject: [NSValue valueWithPointer: descriptor] forKey: [self keyForObjCType: type]];
+}
+
++(NSString *)descriptionForValue:(const void *)ref ofObjCType:(const char *)type {
+ RXAssertionHelperDescriptionFunction function = [self descriptionFunctionForObjCType: type] ?: RXAssertionHelperHexadecimalDescription;
+ return function(ref);
+}
+
+
++(double)floatingPointComparisonAccuracy {
+ return RXAssertionHelperFloatingPointComparisonAccuracy;
+}
+
++(void)setFloatingPointComparisonAccuracy:(double)epsilon {
+ RXAssertionHelperFloatingPointComparisonAccuracy = epsilon;
+}
+
+
++(NSString *)humanReadableNameForTestCaseSelector:(SEL)selector {
+ NSMutableArray *words = [NSMutableArray array];
+ NSScanner *scanner = [NSScanner scannerWithString: NSStringFromSelector(selector)];
+ [scanner scanString: @"test" intoString: nil]; // skip "test"
+ while(!scanner.isAtEnd) {
+ NSString *up = nil, *lo = nil;
+ NSUInteger cursor = scanner.scanLocation;
+ up = [scanner.string substringWithRange: NSMakeRange(cursor, 1)]; // grab the first character
+ scanner.scanLocation = cursor + 1;
+ [scanner scanCharactersFromSet: [NSCharacterSet lowercaseLetterCharacterSet] intoString: &lo];
+ [words addObject: [NSString stringWithFormat: @"%@%@", [up lowercaseString], lo ?: @""]];
+ }
+ return [words componentsJoinedByString: @" "];
+}
+
++(NSString *)humanReadableNameForTestSuiteClass:(Class)klass {
+ NSString *name = NSStringFromClass(klass);
+ NSString *result = name;
+ NSRange testsRange = [name rangeOfString: @"Tests" options: NSBackwardsSearch | NSAnchoredSearch];
+ NSRange testRange = [name rangeOfString: @"Test" options: NSBackwardsSearch | NSAnchoredSearch];
+ if(testsRange.location != NSNotFound) {
+ result = [name substringToIndex: testsRange.location];
+ } else if(testRange.location != NSNotFound) {
+ result = [name substringToIndex: testRange.location];
+ }
+ return result;
+}
+
+@end
+
+
+@implementation SenTestCase (RXAssertionsPrettierNamesForTestCases)
+
+//-(NSString *)name {
+// return [NSString stringWithFormat: @"%@ %@", [RXAssertionHelper humanReadableNameForTestSuiteClass: self.class], [RXAssertionHelper humanReadableNameForTestCaseSelector: self.invocation.selector]];
+//}
+
+@end
View
22 External/RXSynchronously/RXSynchronouslyTests/RXSynchronouslyTests-Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.monochromeindustries.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
View
44 External/RXSynchronously/RXSynchronouslyTests/RXSynchronouslyTests.m
@@ -0,0 +1,44 @@
+// RXSynchronouslyTests.m
+// Created by Rob Rix on 11-11-27.
+// Copyright (c) 2011 Monochrome Industries. All rights reserved.
+
+#import "RXAssertions.h"
+#import "RXSynchronously.h"
+
+@interface RXSynchronouslyTests : SenTestCase
+@end
+
+@implementation RXSynchronouslyTests
+
+-(void)testSynchronizesOnTheCompletionOfAsynchronousWork {
+ NSMutableArray *completedActions = [NSMutableArray new];
+ RXSynchronously(^(RXSynchronousCompletionBlock didComplete) {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ [completedActions addObject:@"async"];
+ didComplete();
+ });
+ });
+ [completedActions addObject:@"sync"];
+
+ RXAssertEquals(completedActions, ([NSArray arrayWithObjects:@"async", @"sync", nil]));
+}
+
+
+-(void)testTimesOutAfterASpecifiedWait {
+ // this test has a race condition:
+ // completedActions is not being serialized, and theoretically RXSynchronouslyWithTimeout could take the full second that the async block sleeps to complete
+ // unlikely, but worth noting
+ NSMutableArray *completedActions = [NSMutableArray new];
+ RXSynchronouslyWithTimeout(DISPATCH_TIME_NOW, ^(RXSynchronousCompletionBlock didComplete) {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ sleep(1);
+ [completedActions addObject:@"async"];
+ didComplete();
+ });
+ });
+ [completedActions addObject:@"sync"];
+
+ RXAssertEquals(completedActions, [NSArray arrayWithObject:@"sync"]);
+}
+
+@end
View
2 External/RXSynchronously/RXSynchronouslyTests/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+

0 comments on commit 84fcd6f

Please sign in to comment.
Something went wrong with that request. Please try again.