From 5a0532cbfd530d4e59bef785b6e2945f9bbaa058 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Sun, 9 Apr 2017 02:18:31 +0900 Subject: [PATCH 01/29] Reinitialize the package by SwiftPM --- .gitignore | 7 +- Package.swift | 2 + PromiseK.xcodeproj/Configs/Project.xcconfig | 7 - PromiseK.xcodeproj/project.pbxproj | 282 ++++++++++-------- .../xcshareddata/xcschemes/PromiseK.xcscheme | 6 +- Sources/PromiseK.h | 11 - Tests/LinuxMain.swift | 4 +- 7 files changed, 160 insertions(+), 159 deletions(-) delete mode 100644 PromiseK.xcodeproj/Configs/Project.xcconfig delete mode 100644 Sources/PromiseK.h diff --git a/.gitignore b/.gitignore index 9debffb..02c0875 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ +.DS_Store /.build -/*.xcodeproj/xcshareddata/ -/*.xcodeproj/project.xcworkspace/xcuserdata/ -/*.xcodeproj/xcuserdata/ -/Carthage +/Packages +/*.xcodeproj diff --git a/Package.swift b/Package.swift index 998b193..98ef787 100644 --- a/Package.swift +++ b/Package.swift @@ -1,3 +1,5 @@ +// swift-tools-version:3.1 + import PackageDescription let package = Package( diff --git a/PromiseK.xcodeproj/Configs/Project.xcconfig b/PromiseK.xcodeproj/Configs/Project.xcconfig deleted file mode 100644 index 5f63024..0000000 --- a/PromiseK.xcodeproj/Configs/Project.xcconfig +++ /dev/null @@ -1,7 +0,0 @@ -PRODUCT_NAME = $(TARGET_NAME) -SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator -MACOSX_DEPLOYMENT_TARGET = 10.10 -DYLIB_INSTALL_NAME_BASE = @rpath -OTHER_SWIFT_FLAGS = -DXcode -COMBINE_HIDPI_IMAGES = YES -USE_HEADERMAP = NO diff --git a/PromiseK.xcodeproj/project.pbxproj b/PromiseK.xcodeproj/project.pbxproj index b82050a..9b67d50 100644 --- a/PromiseK.xcodeproj/project.pbxproj +++ b/PromiseK.xcodeproj/project.pbxproj @@ -7,131 +7,105 @@ objects = { /* Begin PBXBuildFile section */ - _LinkFileRef_PromiseK_via_PromiseKTests /* PromiseK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "_____Product_PromiseK" /* PromiseK.framework */; }; - __src_cc_ref_Sources/Operators.swift /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = __PBXFileRef_Sources/Operators.swift /* Operators.swift */; }; - __src_cc_ref_Sources/Promise.swift /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = __PBXFileRef_Sources/Promise.swift /* Promise.swift */; }; - __src_cc_ref_Tests/PromiseKTests/PromiseKTests.swift /* PromiseKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = __PBXFileRef_Tests/PromiseKTests/PromiseKTests.swift /* PromiseKTests.swift */; }; + OBJ_21 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_8 /* Operators.swift */; }; + OBJ_22 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* Promise.swift */; }; + OBJ_29 /* PromiseKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* PromiseKTests.swift */; }; + OBJ_31 /* PromiseK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* PromiseK.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - D628F9C81DC99FA0004C8356 /* PBXContainerItemProxy */ = { + D687D5DC1E994BB1006EA0C7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = __RootObject_ /* Project object */; + containerPortal = OBJ_1 /* Project object */; proxyType = 1; - remoteGlobalIDString = "______Target_PromiseK"; + remoteGlobalIDString = OBJ_16; remoteInfo = PromiseK; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - __PBXFileRef_Package.swift /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; - __PBXFileRef_PromiseK.xcodeproj/Configs/Project.xcconfig /* PromiseK.xcodeproj/Configs/Project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = PromiseK.xcodeproj/Configs/Project.xcconfig; sourceTree = ""; }; - __PBXFileRef_Sources/Operators.swift /* Operators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; }; - __PBXFileRef_Sources/Promise.swift /* Promise.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Promise.swift; sourceTree = ""; }; - __PBXFileRef_Tests/PromiseKTests/PromiseKTests.swift /* PromiseKTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromiseKTests.swift; sourceTree = ""; }; - "_____Product_PromiseK" /* PromiseK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PromiseK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - "_____Product_PromiseKTests" /* PromiseKTests.xctest */ = {isa = PBXFileReference; lastKnownFileType = file; path = PromiseKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + OBJ_12 /* PromiseKTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromiseKTests.swift; sourceTree = ""; }; + OBJ_14 /* PromiseK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PromiseK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + OBJ_15 /* PromiseKTests.xctest */ = {isa = PBXFileReference; lastKnownFileType = file; path = PromiseKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; + OBJ_8 /* Operators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; }; + OBJ_9 /* Promise.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Promise.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - "___LinkPhase_PromiseK" /* Frameworks */ = { + OBJ_23 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 0; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - "___LinkPhase_PromiseKTests" /* Frameworks */ = { + OBJ_30 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 0; files = ( - _LinkFileRef_PromiseK_via_PromiseKTests /* PromiseK.framework in Frameworks */, + OBJ_31 /* PromiseK.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - TestProducts_ /* Tests */ = { + OBJ_10 /* Tests */ = { isa = PBXGroup; children = ( - "_____Product_PromiseKTests" /* PromiseKTests.xctest */, + OBJ_11 /* PromiseKTests */, ); name = Tests; - sourceTree = ""; + sourceTree = SOURCE_ROOT; }; - "___RootGroup_" = { + OBJ_11 /* PromiseKTests */ = { isa = PBXGroup; children = ( - __PBXFileRef_Package.swift /* Package.swift */, - "_____Configs_" /* Configs */, - "_____Sources_" /* Sources */, - "_______Tests_" /* Tests */, - "____Products_" /* Products */, + OBJ_12 /* PromiseKTests.swift */, ); - sourceTree = ""; + name = PromiseKTests; + path = Tests/PromiseKTests; + sourceTree = SOURCE_ROOT; }; - "____Products_" /* Products */ = { + OBJ_13 /* Products */ = { isa = PBXGroup; children = ( - TestProducts_ /* Tests */, - "_____Product_PromiseK" /* PromiseK.framework */, + OBJ_14 /* PromiseK.framework */, + OBJ_15 /* PromiseKTests.xctest */, ); name = Products; - sourceTree = ""; - }; - "_____Configs_" /* Configs */ = { - isa = PBXGroup; - children = ( - __PBXFileRef_PromiseK.xcodeproj/Configs/Project.xcconfig /* PromiseK.xcodeproj/Configs/Project.xcconfig */, - ); - name = Configs; - sourceTree = ""; + sourceTree = BUILT_PRODUCTS_DIR; }; - "_____Sources_" /* Sources */ = { + OBJ_5 /* */ = { isa = PBXGroup; children = ( - "_______Group_PromiseK" /* PromiseK */, + OBJ_6 /* Package.swift */, + OBJ_7 /* Sources */, + OBJ_10 /* Tests */, + OBJ_13 /* Products */, ); - name = Sources; + name = ""; sourceTree = ""; }; - "_______Group_PromiseK" /* PromiseK */ = { + OBJ_7 /* Sources */ = { isa = PBXGroup; children = ( - __PBXFileRef_Sources/Operators.swift /* Operators.swift */, - __PBXFileRef_Sources/Promise.swift /* Promise.swift */, + OBJ_8 /* Operators.swift */, + OBJ_9 /* Promise.swift */, ); - name = PromiseK; path = Sources; - sourceTree = ""; - }; - "_______Group_PromiseKTests" /* PromiseKTests */ = { - isa = PBXGroup; - children = ( - __PBXFileRef_Tests/PromiseKTests/PromiseKTests.swift /* PromiseKTests.swift */, - ); - name = PromiseKTests; - path = Tests/PromiseKTests; - sourceTree = ""; - }; - "_______Tests_" /* Tests */ = { - isa = PBXGroup; - children = ( - "_______Group_PromiseKTests" /* PromiseKTests */, - ); - name = Tests; - sourceTree = ""; + sourceTree = SOURCE_ROOT; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - "______Target_PromiseK" /* PromiseK */ = { + OBJ_16 /* PromiseK */ = { isa = PBXNativeTarget; - buildConfigurationList = "_______Confs_PromiseK" /* Build configuration list for PBXNativeTarget "PromiseK" */; + buildConfigurationList = OBJ_17 /* Build configuration list for PBXNativeTarget "PromiseK" */; buildPhases = ( - CompilePhase_PromiseK /* Sources */, - "___LinkPhase_PromiseK" /* Frameworks */, + OBJ_20 /* Sources */, + OBJ_23 /* Frameworks */, ); buildRules = ( ); @@ -139,86 +113,90 @@ ); name = PromiseK; productName = PromiseK; - productReference = "_____Product_PromiseK" /* PromiseK.framework */; + productReference = OBJ_14 /* PromiseK.framework */; productType = "com.apple.product-type.framework"; }; - "______Target_PromiseKTests" /* PromiseKTests */ = { + OBJ_24 /* PromiseKTests */ = { isa = PBXNativeTarget; - buildConfigurationList = "_______Confs_PromiseKTests" /* Build configuration list for PBXNativeTarget "PromiseKTests" */; + buildConfigurationList = OBJ_25 /* Build configuration list for PBXNativeTarget "PromiseKTests" */; buildPhases = ( - CompilePhase_PromiseKTests /* Sources */, - "___LinkPhase_PromiseKTests" /* Frameworks */, + OBJ_28 /* Sources */, + OBJ_30 /* Frameworks */, ); buildRules = ( ); dependencies = ( - __Dependency_PromiseK /* PBXTargetDependency */, + OBJ_32 /* PBXTargetDependency */, ); name = PromiseKTests; productName = PromiseKTests; - productReference = "_____Product_PromiseKTests" /* PromiseKTests.xctest */; + productReference = OBJ_15 /* PromiseKTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - __RootObject_ /* Project object */ = { + OBJ_1 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 9999; }; - buildConfigurationList = "___RootConfs_" /* Build configuration list for PBXProject "PromiseK" */; + buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "PromiseK" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); - mainGroup = "___RootGroup_"; - productRefGroup = "____Products_" /* Products */; + mainGroup = OBJ_5 /* */; + productRefGroup = OBJ_13 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - "______Target_PromiseK" /* PromiseK */, - "______Target_PromiseKTests" /* PromiseKTests */, + OBJ_16 /* PromiseK */, + OBJ_24 /* PromiseKTests */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - CompilePhase_PromiseK /* Sources */ = { + OBJ_20 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 0; files = ( - __src_cc_ref_Sources/Operators.swift /* Operators.swift in Sources */, - __src_cc_ref_Sources/Promise.swift /* Promise.swift in Sources */, + OBJ_21 /* Operators.swift in Sources */, + OBJ_22 /* Promise.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - CompilePhase_PromiseKTests /* Sources */ = { + OBJ_28 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 0; files = ( - __src_cc_ref_Tests/PromiseKTests/PromiseKTests.swift /* PromiseKTests.swift in Sources */, + OBJ_29 /* PromiseKTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - __Dependency_PromiseK /* PBXTargetDependency */ = { + OBJ_32 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = "______Target_PromiseK" /* PromiseK */; - targetProxy = D628F9C81DC99FA0004C8356 /* PBXContainerItemProxy */; + target = OBJ_16 /* PromiseK */; + targetProxy = D687D5DC1E994BB1006EA0C7 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - _ReleaseConf_PromiseK /* Release */ = { + OBJ_18 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = "$(PLATFORM_DIR)/Developer/Library/Frameworks"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = PromiseK.xcodeproj/PromiseK_Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; OTHER_LDFLAGS = "$(inherited)"; @@ -226,28 +204,20 @@ PRODUCT_BUNDLE_IDENTIFIER = PromiseK; PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SWIFT_VERSION = 3.0; - }; - name = Release; - }; - _ReleaseConf_PromiseKTests /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; - FRAMEWORK_SEARCH_PATHS = "$(PLATFORM_DIR)/Developer/Library/Frameworks"; - INFOPLIST_FILE = PromiseK.xcodeproj/PromiseKTests_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - SWIFT_VERSION = 3.0; + SKIP_INSTALL = YES; + TARGET_NAME = PromiseK; }; - name = Release; + name = Debug; }; - "___DebugConf_PromiseK" /* Debug */ = { + OBJ_19 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = "$(PLATFORM_DIR)/Developer/Library/Frameworks"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = PromiseK.xcodeproj/PromiseK_Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; OTHER_LDFLAGS = "$(inherited)"; @@ -255,72 +225,120 @@ PRODUCT_BUNDLE_IDENTIFIER = PromiseK; PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SKIP_INSTALL = YES; + TARGET_NAME = PromiseK; }; - name = Debug; + name = Release; }; - "___DebugConf_PromiseKTests" /* Debug */ = { + OBJ_26 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; - FRAMEWORK_SEARCH_PATHS = "$(PLATFORM_DIR)/Developer/Library/Frameworks"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = PromiseK.xcodeproj/PromiseKTests_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/Frameworks"; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + TARGET_NAME = PromiseKTests; }; name = Debug; }; - "_____Release_" /* Release */ = { + OBJ_27 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = __PBXFileRef_PromiseK.xcodeproj/Configs/Project.xcconfig /* PromiseK.xcodeproj/Configs/Project.xcconfig */; buildSettings = { - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = PromiseK.xcodeproj/PromiseKTests_Info.plist; + LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/Frameworks"; + OTHER_LDFLAGS = "$(inherited)"; + OTHER_SWIFT_FLAGS = "$(inherited)"; + TARGET_NAME = PromiseKTests; }; name = Release; }; - "_______Debug_" /* Debug */ = { + OBJ_3 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = __PBXFileRef_PromiseK.xcodeproj/Configs/Project.xcconfig /* PromiseK.xcodeproj/Configs/Project.xcconfig */; buildSettings = { - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + CLANG_ENABLE_OBJC_ARC = YES; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + MACOSX_DEPLOYMENT_TARGET = 10.10; + ONLY_ACTIVE_ARCH = YES; + OTHER_SWIFT_FLAGS = "-DXcode"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + USE_HEADERMAP = NO; }; name = Debug; }; + OBJ_4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_OPTIMIZATION_LEVEL = s; + MACOSX_DEPLOYMENT_TARGET = 10.10; + OTHER_SWIFT_FLAGS = "-DXcode"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; + USE_HEADERMAP = NO; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - "___RootConfs_" /* Build configuration list for PBXProject "PromiseK" */ = { + OBJ_17 /* Build configuration list for PBXNativeTarget "PromiseK" */ = { isa = XCConfigurationList; buildConfigurations = ( - "_______Debug_" /* Debug */, - "_____Release_" /* Release */, + OBJ_18 /* Debug */, + OBJ_19 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - "_______Confs_PromiseK" /* Build configuration list for PBXNativeTarget "PromiseK" */ = { + OBJ_2 /* Build configuration list for PBXProject "PromiseK" */ = { isa = XCConfigurationList; buildConfigurations = ( - "___DebugConf_PromiseK" /* Debug */, - _ReleaseConf_PromiseK /* Release */, + OBJ_3 /* Debug */, + OBJ_4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - "_______Confs_PromiseKTests" /* Build configuration list for PBXNativeTarget "PromiseKTests" */ = { + OBJ_25 /* Build configuration list for PBXNativeTarget "PromiseKTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - "___DebugConf_PromiseKTests" /* Debug */, - _ReleaseConf_PromiseKTests /* Release */, + OBJ_26 /* Debug */, + OBJ_27 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ }; - rootObject = __RootObject_ /* Project object */; + rootObject = OBJ_1 /* Project object */; } diff --git a/PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK.xcscheme b/PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK.xcscheme index 6a3f3af..08e050e 100644 --- a/PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK.xcscheme +++ b/PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> @@ -32,7 +32,7 @@ skipped = "NO"> @@ -55,7 +55,7 @@ diff --git a/Sources/PromiseK.h b/Sources/PromiseK.h deleted file mode 100644 index f8b9758..0000000 --- a/Sources/PromiseK.h +++ /dev/null @@ -1,11 +0,0 @@ -#import - -//! Project version number for PromiseK. -FOUNDATION_EXPORT double PromiseKVersionNumber; - -//! Project version string for PromiseK. -FOUNDATION_EXPORT const unsigned char PromiseKVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 7250b83..f12c409 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -1,6 +1,6 @@ import XCTest -@testable import PromisureTests +@testable import PromiseKTests XCTMain([ - testCase(PromisureTests.allTests), + testCase(PromiseKTests.allTests), ]) From a30a4949c763037e20a1087609430d07203ef93c Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 2 May 2017 11:56:48 +0900 Subject: [PATCH 02/29] Remove the xcodeproj --- PromiseK.xcodeproj/PromiseKTests_Info.plist | 25 -- PromiseK.xcodeproj/PromiseK_Info.plist | 25 -- PromiseK.xcodeproj/project.pbxproj | 344 ------------------ .../contents.xcworkspacedata | 7 - .../xcshareddata/xcschemes/PromiseK.xcscheme | 81 ----- .../xcschemes/xcschememanagement.plist | 12 - 6 files changed, 494 deletions(-) delete mode 100644 PromiseK.xcodeproj/PromiseKTests_Info.plist delete mode 100644 PromiseK.xcodeproj/PromiseK_Info.plist delete mode 100644 PromiseK.xcodeproj/project.pbxproj delete mode 100644 PromiseK.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK.xcscheme delete mode 100644 PromiseK.xcodeproj/xcshareddata/xcschemes/xcschememanagement.plist diff --git a/PromiseK.xcodeproj/PromiseKTests_Info.plist b/PromiseK.xcodeproj/PromiseKTests_Info.plist deleted file mode 100644 index 7c23420..0000000 --- a/PromiseK.xcodeproj/PromiseKTests_Info.plist +++ /dev/null @@ -1,25 +0,0 @@ - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/PromiseK.xcodeproj/PromiseK_Info.plist b/PromiseK.xcodeproj/PromiseK_Info.plist deleted file mode 100644 index 57ada9f..0000000 --- a/PromiseK.xcodeproj/PromiseK_Info.plist +++ /dev/null @@ -1,25 +0,0 @@ - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/PromiseK.xcodeproj/project.pbxproj b/PromiseK.xcodeproj/project.pbxproj deleted file mode 100644 index 9b67d50..0000000 --- a/PromiseK.xcodeproj/project.pbxproj +++ /dev/null @@ -1,344 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - OBJ_21 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_8 /* Operators.swift */; }; - OBJ_22 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* Promise.swift */; }; - OBJ_29 /* PromiseKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* PromiseKTests.swift */; }; - OBJ_31 /* PromiseK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* PromiseK.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - D687D5DC1E994BB1006EA0C7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = OBJ_1 /* Project object */; - proxyType = 1; - remoteGlobalIDString = OBJ_16; - remoteInfo = PromiseK; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - OBJ_12 /* PromiseKTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromiseKTests.swift; sourceTree = ""; }; - OBJ_14 /* PromiseK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PromiseK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - OBJ_15 /* PromiseKTests.xctest */ = {isa = PBXFileReference; lastKnownFileType = file; path = PromiseKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; - OBJ_8 /* Operators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; }; - OBJ_9 /* Promise.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Promise.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - OBJ_23 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_30 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 0; - files = ( - OBJ_31 /* PromiseK.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - OBJ_10 /* Tests */ = { - isa = PBXGroup; - children = ( - OBJ_11 /* PromiseKTests */, - ); - name = Tests; - sourceTree = SOURCE_ROOT; - }; - OBJ_11 /* PromiseKTests */ = { - isa = PBXGroup; - children = ( - OBJ_12 /* PromiseKTests.swift */, - ); - name = PromiseKTests; - path = Tests/PromiseKTests; - sourceTree = SOURCE_ROOT; - }; - OBJ_13 /* Products */ = { - isa = PBXGroup; - children = ( - OBJ_14 /* PromiseK.framework */, - OBJ_15 /* PromiseKTests.xctest */, - ); - name = Products; - sourceTree = BUILT_PRODUCTS_DIR; - }; - OBJ_5 /* */ = { - isa = PBXGroup; - children = ( - OBJ_6 /* Package.swift */, - OBJ_7 /* Sources */, - OBJ_10 /* Tests */, - OBJ_13 /* Products */, - ); - name = ""; - sourceTree = ""; - }; - OBJ_7 /* Sources */ = { - isa = PBXGroup; - children = ( - OBJ_8 /* Operators.swift */, - OBJ_9 /* Promise.swift */, - ); - path = Sources; - sourceTree = SOURCE_ROOT; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - OBJ_16 /* PromiseK */ = { - isa = PBXNativeTarget; - buildConfigurationList = OBJ_17 /* Build configuration list for PBXNativeTarget "PromiseK" */; - buildPhases = ( - OBJ_20 /* Sources */, - OBJ_23 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = PromiseK; - productName = PromiseK; - productReference = OBJ_14 /* PromiseK.framework */; - productType = "com.apple.product-type.framework"; - }; - OBJ_24 /* PromiseKTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = OBJ_25 /* Build configuration list for PBXNativeTarget "PromiseKTests" */; - buildPhases = ( - OBJ_28 /* Sources */, - OBJ_30 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - OBJ_32 /* PBXTargetDependency */, - ); - name = PromiseKTests; - productName = PromiseKTests; - productReference = OBJ_15 /* PromiseKTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - OBJ_1 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 9999; - }; - buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "PromiseK" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = OBJ_5 /* */; - productRefGroup = OBJ_13 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - OBJ_16 /* PromiseK */, - OBJ_24 /* PromiseKTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - OBJ_20 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 0; - files = ( - OBJ_21 /* Operators.swift in Sources */, - OBJ_22 /* Promise.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_28 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 0; - files = ( - OBJ_29 /* PromiseKTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - OBJ_32 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = OBJ_16 /* PromiseK */; - targetProxy = D687D5DC1E994BB1006EA0C7 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - OBJ_18 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = PromiseK.xcodeproj/PromiseK_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = PromiseK; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - TARGET_NAME = PromiseK; - }; - name = Debug; - }; - OBJ_19 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = PromiseK.xcodeproj/PromiseK_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = PromiseK; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - TARGET_NAME = PromiseK; - }; - name = Release; - }; - OBJ_26 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = PromiseK.xcodeproj/PromiseKTests_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/Frameworks"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - TARGET_NAME = PromiseKTests; - }; - name = Debug; - }; - OBJ_27 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = PromiseK.xcodeproj/PromiseKTests_Info.plist; - LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks @loader_path/Frameworks"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - TARGET_NAME = PromiseKTests; - }; - name = Release; - }; - OBJ_3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_NS_ASSERTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - MACOSX_DEPLOYMENT_TARGET = 10.10; - ONLY_ACTIVE_ARCH = YES; - OTHER_SWIFT_FLAGS = "-DXcode"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - USE_HEADERMAP = NO; - }; - name = Debug; - }; - OBJ_4 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_OPTIMIZATION_LEVEL = s; - MACOSX_DEPLOYMENT_TARGET = 10.10; - OTHER_SWIFT_FLAGS = "-DXcode"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; - USE_HEADERMAP = NO; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - OBJ_17 /* Build configuration list for PBXNativeTarget "PromiseK" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_18 /* Debug */, - OBJ_19 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - OBJ_2 /* Build configuration list for PBXProject "PromiseK" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_3 /* Debug */, - OBJ_4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - OBJ_25 /* Build configuration list for PBXNativeTarget "PromiseKTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_26 /* Debug */, - OBJ_27 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; -/* End XCConfigurationList section */ - }; - rootObject = OBJ_1 /* Project object */; -} diff --git a/PromiseK.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/PromiseK.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a..0000000 --- a/PromiseK.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK.xcscheme b/PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK.xcscheme deleted file mode 100644 index 08e050e..0000000 --- a/PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK.xcscheme +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PromiseK.xcodeproj/xcshareddata/xcschemes/xcschememanagement.plist b/PromiseK.xcodeproj/xcshareddata/xcschemes/xcschememanagement.plist deleted file mode 100644 index 55b2377..0000000 --- a/PromiseK.xcodeproj/xcshareddata/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,12 +0,0 @@ - - - - SchemeUserState - - PromiseK.xcscheme - - - SuppressBuildableAutocreation - - - From aca7025d2ed98b2b9a6d66700801f0fb6571309c Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 2 May 2017 12:03:58 +0900 Subject: [PATCH 03/29] Remove operators and `apply` --- Sources/Operators.swift | 26 --- Sources/Promise.swift | 46 +---- Tests/PromiseKTests/PromiseKTests.swift | 215 +----------------------- 3 files changed, 6 insertions(+), 281 deletions(-) delete mode 100644 Sources/Operators.swift diff --git a/Sources/Operators.swift b/Sources/Operators.swift deleted file mode 100644 index dccc4ad..0000000 --- a/Sources/Operators.swift +++ /dev/null @@ -1,26 +0,0 @@ -precedencegroup PromiseKMonadicPrecedenceRight { - associativity: right - lowerThan: LogicalDisjunctionPrecedence - higherThan: AssignmentPrecedence -} - -precedencegroup PromiseKMonadicPrecedenceLeft { - associativity: left - lowerThan: LogicalDisjunctionPrecedence - higherThan: AssignmentPrecedence -} - -precedencegroup PromiseKApplicativePrecedence { - associativity: left - higherThan: LogicalConjunctionPrecedence - lowerThan: NilCoalescingPrecedence -} - -infix operator >>- : PromiseKMonadicPrecedenceLeft -infix operator -<< : PromiseKMonadicPrecedenceRight - -infix operator <^> : PromiseKApplicativePrecedence -infix operator <*> : PromiseKApplicativePrecedence - -infix operator >>-? : PromiseKMonadicPrecedenceLeft -infix operator -< { +public class Promise { fileprivate let lock = NSRecursiveLock() fileprivate var value: T? @@ -39,17 +39,13 @@ open class Promise { lock.unlock() } - open func map(_ f: @escaping (T) -> U) -> Promise { + public func map(_ f: @escaping (T) -> U) -> Promise { return flatMap { Promise(f($0)) } } - open func flatMap(_ f: @escaping (T) -> Promise) -> Promise { + public func flatMap(_ f: @escaping (T) -> Promise) -> Promise { return Promise { resolve in self.reserve { resolve(f($0)) } } } - - open func apply(_ f: Promise<(T) -> U>) -> Promise { - return f.flatMap { self.map($0) } - } } extension Promise : CustomStringConvertible { @@ -61,39 +57,3 @@ extension Promise : CustomStringConvertible { } } } - -public func pure(_ x: T) -> Promise { - return Promise(x) -} - -public func flatten(_ x: Promise>) -> Promise { - return x.flatMap { $0 } -} - -public func >>-(lhs: Promise, rhs: @escaping (T) -> Promise) -> Promise { - return lhs.flatMap(rhs) -} - -public func >>-?(lhs: Promise, rhs: @escaping (T) -> Promise) -> Promise { - return lhs.flatMap { $0.map(rhs) ?? Promise(nil) } -} - -public func >>-(lhs: Promise, rhs: @escaping (T?) -> Promise?) -> Promise { - return lhs.flatMap { rhs($0) ?? Promise(nil) } -} - -public func -<<(lhs: @escaping (T) -> Promise, rhs: Promise) -> Promise { - return rhs.flatMap(lhs) -} - -public func -<(lhs: @escaping (T) -> Promise, rhs: Promise) -> Promise { - return rhs >>-? lhs -} - -public func <^>(lhs: @escaping (T) -> U, rhs: Promise) -> Promise { - return rhs.map(lhs) -} - -public func <*>(lhs: Promise<(T) -> U>, rhs: Promise) -> Promise { - return rhs.apply(lhs) -} diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index ea520fb..f97905e 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -1,22 +1,7 @@ import XCTest -import PromiseK +@testable import PromiseK class PromiseKTests: XCTestCase { - func testPure() { - let expectation = self.expectation(description: "") - - var result: Int = 0 - let promise: Promise = pure(2) - _ = promise.map { - result = $0 - expectation.fulfill() - } - - waitForExpectations(timeout: 3.0, handler: nil) - - XCTAssertEqual(2, result) - } - func testMap() { let expectation = self.expectation(description: "") @@ -60,183 +45,6 @@ class PromiseKTests: XCTestCase { } } - func testFlatMapOperator() { - do { - let expectation = self.expectation(description: "") - - _ = asyncGet(3) >>- { (value: Int) -> Promise<()> in - XCTAssertEqual(value, 3) - expectation.fulfill() - return Promise<()>() - } - - waitForExpectations(timeout: 3.0, handler: nil) - } - - do { - let expectation = self.expectation(description: "") - - _ = asyncGet(3) >>- { (value: Int) in - XCTAssertEqual(value, 3) - return asyncGet(value * value) - } >>- { (value: Int) -> Promise<()> in - XCTAssertEqual(value, 9) - expectation.fulfill() - return Promise<()>() - } - - waitForExpectations(timeout: 3.0, handler: nil) - } - - do { - let expectation = self.expectation(description: "") - - _ = asyncGetOrFail(3, false) >>- { (valueOrNil: Int?) -> Promise? in - valueOrNil.map { value in - XCTAssertEqual(value, 3) - return asyncGetOrFail(value * value, false) - } - } >>- { (valueOrNil: Int?) -> Promise<()> in - if let value = valueOrNil { - XCTAssertEqual(value, 9) - } else { - XCTFail() - } - expectation.fulfill() - return Promise<()>() - } - - waitForExpectations(timeout: 3.0, handler: nil) - } - - do { - let expectation = self.expectation(description: "") - - _ = asyncGetOrFail(3, false) >>- { (valueOrNil: Int?) -> Promise? in - valueOrNil.map { value in - XCTAssertEqual(value, 3) - return asyncGetOrFail(value * value, true) - } - } >>- { (valueOrNil: Int?) -> Promise<()> in - XCTAssertTrue(valueOrNil == nil) - expectation.fulfill() - return Promise<()>() - } - - waitForExpectations(timeout: 3.0, handler: nil) - } - - do { - let expectation = self.expectation(description: "") - - _ = asyncGetOrFail(3, true) >>- { (valueOrNil: Int?) -> Promise? in - XCTAssertTrue(valueOrNil == nil) - return valueOrNil.map { value in - XCTFail() - return asyncGetOrFail(value * value, true) - } - } >>- { (valueOrNil: Int?) -> Promise<()> in - XCTAssertTrue(valueOrNil == nil) - expectation.fulfill() - return Promise<()>() - } - - waitForExpectations(timeout: 3.0, handler: nil) - } - } - - func testFlatMapQOperator() { - do { - let expectation = self.expectation(description: "") - - _ = asyncGetOrFail(3, false) >>-? { value in - XCTAssertEqual(value, 3) - return asyncGetOrFail(value * value, false) - } >>- { (valueOrNil: Int?) -> Promise<()> in - if let value = valueOrNil { - XCTAssertEqual(value, 9) - } else { - XCTFail() - } - expectation.fulfill() - return Promise<()>() - } - - waitForExpectations(timeout: 3.0, handler: nil) - } - - do { - let expectation = self.expectation(description: "") - - _ = asyncGetOrFail(3, false) >>-? { value in - XCTAssertEqual(value, 3) - return asyncGetOrFail(value * value, true) - } >>- { (valueOrNil: Int?) -> Promise<()> in - XCTAssertTrue(valueOrNil == nil) - expectation.fulfill() - return Promise<()>() - } - - waitForExpectations(timeout: 3.0, handler: nil) - } - - do { - let expectation = self.expectation(description: "") - - _ = asyncGetOrFail(3, true) >>-? { value in - XCTFail() - return asyncGetOrFail(value * value, true) - } >>- { (valueOrNil: Int?) -> Promise<()> in - XCTAssertTrue(valueOrNil == nil) - expectation.fulfill() - return Promise<()>() - } - - waitForExpectations(timeout: 3.0, handler: nil) - } - } - - func testFlippedFlatMapOperator() { - do { - let expectation = self.expectation(description: ""); // this ; is necessary - - _ = { (value: Int) -> Promise<()> in - XCTAssertEqual(value, 3) - expectation.fulfill() - return Promise<()>() - } -<< asyncGet(3) - - waitForExpectations(timeout: 3.0, handler: nil) - } - } - - func testFlippedFlatMapQOperator() { - do { - let expectation = self.expectation(description: ""); // this ; is necessary - - _ = { (value: Int) -> Promise<()?> in - XCTAssertEqual(value, 3) - expectation.fulfill() - return Promise<()?>(.some()) - } -< asyncGet(2) <*> asyncGet(3)) >>- { (a: Int, b: Int) -> Promise<()> in - XCTAssertEqual(a, 2) - XCTAssertEqual(b, 3) - expectation.fulfill() - return Promise<()>() - } - - waitForExpectations(timeout: 3.0, handler: nil) - } - func testSynchronization() { let queue1 = DispatchQueue(label: "foo", attributes: []) let queue2 = DispatchQueue(label: "bar", attributes: []) @@ -246,14 +54,14 @@ class PromiseKTests: XCTestCase { let promise = Promise { resolve in queue1.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.01 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { - resolve(pure(2)) + resolve(Promise(2)) } } queue2.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.01 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { let _: Promise = promise.flatMap { expectation.fulfill() - return pure($0 * $0) + return Promise($0 * $0) } } @@ -271,14 +79,6 @@ class PromiseKTests: XCTestCase { let mightFail: Promise = asyncFailable(5).flatMap { Promise($0.map { $0 * $0 }) } let howToCatch: Promise = asyncFailable(7).flatMap { Promise($0 ?? 0) } - // `>>-` operator is equivalent to `>>=` in Haskell - // can use `>>-` instead of `flatMap` - let a2: Promise = asyncGet(2) >>- { asyncGet($0) } >>- { asyncGet($0) } - // a failable operation chain with `>>-` - let failableChain: Promise = asyncFailable(11) >>- { $0.map { asyncFailable($0) } } - // also `>>-?` operator is available - let failableChain2: Promise = asyncFailable(11) >>-? { asyncFailable($0) } - sum.wait() print(a) print(b) @@ -289,15 +89,6 @@ class PromiseKTests: XCTestCase { howToCatch.wait() print(howToCatch) - - a2.wait() - print(a2) - - failableChain.wait() - print(failableChain) - - failableChain2.wait() - print(failableChain2) } } From ee9c6140fa9593b4fa606ac2753473cb9ff6bddd Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 2 May 2017 12:06:04 +0900 Subject: [PATCH 04/29] Change unnecessary `fileprivate` to `private` --- Sources/Promise.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Promise.swift b/Sources/Promise.swift index 92aa14a..90259aa 100644 --- a/Sources/Promise.swift +++ b/Sources/Promise.swift @@ -1,10 +1,10 @@ import Foundation public class Promise { - fileprivate let lock = NSRecursiveLock() + private let lock = NSRecursiveLock() fileprivate var value: T? - fileprivate var handlers: [(T) -> ()] = [] + private var handlers: [(T) -> ()] = [] public init(_ value: T) { self.value = value @@ -14,7 +14,7 @@ public class Promise { executor(resolve) } - fileprivate func resolve(_ promise: Promise) { + private func resolve(_ promise: Promise) { promise.reserve { self.lock.lock() if self.value == nil { @@ -29,7 +29,7 @@ public class Promise { } } - fileprivate func reserve(_ handler: @escaping (T) -> ()) { + private func reserve(_ handler: @escaping (T) -> ()) { lock.lock() if let value = self.value { handler(value) From a8517d5565a311d97f8e956ccfaaa208fe3e89d1 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 2 May 2017 13:14:28 +0900 Subject: [PATCH 05/29] Rename type parameters --- Sources/Promise.swift | 22 +++++++++++----------- Tests/PromiseKTests/PromiseKTests.swift | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Sources/Promise.swift b/Sources/Promise.swift index 90259aa..79bb6e7 100644 --- a/Sources/Promise.swift +++ b/Sources/Promise.swift @@ -1,20 +1,20 @@ import Foundation -public class Promise { +public class Promise { private let lock = NSRecursiveLock() - fileprivate var value: T? - private var handlers: [(T) -> ()] = [] + fileprivate var value: Value? + private var handlers: [(Value) -> ()] = [] - public init(_ value: T) { + public init(_ value: Value) { self.value = value } - public init(_ executor: (_ resolve: @escaping (Promise) -> ()) -> ()) { + public init(_ executor: (_ resolve: @escaping (Promise) -> ()) -> ()) { executor(resolve) } - private func resolve(_ promise: Promise) { + private func resolve(_ promise: Promise) { promise.reserve { self.lock.lock() if self.value == nil { @@ -29,7 +29,7 @@ public class Promise { } } - private func reserve(_ handler: @escaping (T) -> ()) { + private func reserve(_ handler: @escaping (Value) -> ()) { lock.lock() if let value = self.value { handler(value) @@ -39,12 +39,12 @@ public class Promise { lock.unlock() } - public func map(_ f: @escaping (T) -> U) -> Promise { - return flatMap { Promise(f($0)) } + public func map(_ f: @escaping (Value) -> T) -> Promise { + return flatMap { Promise(f($0)) } } - public func flatMap(_ f: @escaping (T) -> Promise) -> Promise { - return Promise { resolve in self.reserve { resolve(f($0)) } } + public func flatMap(_ f: @escaping (Value) -> Promise) -> Promise { + return Promise { resolve in self.reserve { resolve(f($0)) } } } } diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index f97905e..3a2a234 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -123,7 +123,7 @@ func curry(_ f: @escaping (A, B) -> Z) -> (A) -> (B) -> Z { extension Promise { func wait() { var finished = false - _ = self.flatMap { (value: T) -> Promise<()> in + _ = self.flatMap { (value: Value) -> Promise<()> in finished = true return Promise<()>() } From 97fa9c906af70c9c437a76467aad96ba143228da Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 2 May 2017 13:20:51 +0900 Subject: [PATCH 06/29] Rename `f` to `transform` --- Sources/Promise.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Promise.swift b/Sources/Promise.swift index 79bb6e7..3abf327 100644 --- a/Sources/Promise.swift +++ b/Sources/Promise.swift @@ -39,12 +39,12 @@ public class Promise { lock.unlock() } - public func map(_ f: @escaping (Value) -> T) -> Promise { - return flatMap { Promise(f($0)) } + public func map(_ transform: @escaping (Value) -> T) -> Promise { + return flatMap { Promise(transform($0)) } } - public func flatMap(_ f: @escaping (Value) -> Promise) -> Promise { - return Promise { resolve in self.reserve { resolve(f($0)) } } + public func flatMap(_ transform: @escaping (Value) -> Promise) -> Promise { + return Promise { resolve in self.reserve { resolve(transform($0)) } } } } From 72a39616df7d78fc2be8e637f5700afb2177293b Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 2 May 2017 14:08:25 +0900 Subject: [PATCH 07/29] Update README --- README.md | 44 ++++++++------------------------------------ 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index df6f880..c9285d8 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,26 @@ PromiseK ============================ -_PromiseK_ provides the `Promise` class designed as a _Monad_ for Swift. +_PromiseK_ provides a simple monadic `Promise` type for Swift. ```swift -// `flatMap` is equivalent to `then` of JavaScript's `Promise` +// `map` and `flatMap` are equivalent to `then` of JavaScript's `Promise` let a: Promise = asyncGet(2).flatMap { asyncGet($0) }.flatMap { asyncGet($0) } let b: Promise = asyncGet(3).map { $0 * $0 } let sum: Promise = a.flatMap { a0 in b.flatMap { b0 in Promise(a0 + b0) } } - -// uses `Optional` for error handling -let mightFail: Promise = asyncFailable(5).flatMap { Promise($0.map { $0 * $0 }) } -let howToCatch: Promise = asyncFailable(7).flatMap { Promise($0 ?? 0) } - -// `>>-` operator is equivalent to `>>=` in Haskell -// can use `>>-` instead of `flatMap` -let a2: Promise = asyncGet(2) >>- { asyncGet($0) } >>- { asyncGet($0) } -// a failable operation chain with `>>-` -let failableChain: Promise = asyncFailable(11) >>- { $0.map { asyncFailable($0) } } -// also `>>-?` operator is available -let failableChain2: Promise = asyncFailable(11) >>-? { asyncFailable($0) } ``` Installation ---------------------------- -### Carthage - -[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) - -[_Carthage_](https://github.com/Carthage/Carthage) is available to install _PromiseK_. Add it to your _Cartfile_: +By Swift Package Manager. +```swift +.Package( + url: "https://github.com/koher/PromiseK.git", + majorVersion: 3 +) ``` -github "koher/PromiseK" ~> 2.0 -``` - -### Manually - -#### Embedded Framework - -For iOS 8 or later, - -1. Put [PromiseK.xcodeproj](PromiseK.xcodeproj) into your project in Xcode. -2. Click the project icon and select the "General" tab. -3. Add PromiseK.framework to "Embedded Binaries". -4. `import PromiseK` in your swift files. - -#### Source - -For iOS 7, put all swift files in the [Source](Source) directory into your project. License ---------------------------- From 7746540ae99cf7f99eab7167d86b38fc38dd7466 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 2 May 2017 17:41:31 +0900 Subject: [PATCH 08/29] Implement `map` & `flatMap` for error handling --- Sources/Throws.swift | 32 ++++ Tests/PromiseKTests/PromiseKTests.swift | 199 +++++++++++++++++++++--- 2 files changed, 207 insertions(+), 24 deletions(-) create mode 100644 Sources/Throws.swift diff --git a/Sources/Throws.swift b/Sources/Throws.swift new file mode 100644 index 0000000..f8ed715 --- /dev/null +++ b/Sources/Throws.swift @@ -0,0 +1,32 @@ +extension Promise { + public func map(_ transform: @escaping (Value) throws -> T) -> Promise<() throws -> T> { + return map { value in + do { + let transformed = try transform(value) + return { transformed } + } catch let error { + return { throw error } + } + } + } + + public func flatMap(_ transform: @escaping (Value) throws -> Promise) -> Promise<() throws -> T> { + return flatMap { value in + do { + return try transform(value).map { value in { value } } + } catch let error { + return Promise<() throws -> T>({ throw error }) + } + } + } + + public func flatMap(_ transform: @escaping (Value) throws -> Promise<() throws -> T>) -> Promise<() throws -> T> { + return flatMap { value in + do { + return try transform(value) + } catch let error { + return Promise<() throws -> T>({ throw error }) + } + } + } +} diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index 3a2a234..36a098e 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -20,7 +20,7 @@ class PromiseKTests: XCTestCase { do { let expectation = self.expectation(description: "") - _ = asyncGet(3).flatMap { (value: Int) -> Promise<()> in + _ = asyncGet(3).flatMap { value -> Promise<()> in XCTAssertEqual(value, 3) expectation.fulfill() return Promise<()>() @@ -45,6 +45,121 @@ class PromiseKTests: XCTestCase { } } + func testFailableMap() { + do { + let squared = asyncGetOrFail(3, false).map { + try $0() * $0() + } + + XCTAssertEqual(try squared.sync()(), 9) + } + + do { + let squared = asyncGetOrFail(3, true).map { + try $0() * $0() + } + + _ = try squared.sync()() + XCTFail() + } catch let error as FooError { + XCTAssertEqual(error.value, 3) + } catch _ { + XCTFail() + } + } + + func testFailableFlatMap() { + do { + let a = asyncGetOrFail(2, false) + let b = asyncGetOrFail(3, false) + let sum = a.flatMap { a in + b.map { b in + try a() + b() + } + } + + XCTAssertEqual(try sum.sync()(), 5) + } + + do { + let a = asyncGetOrFail(2, true) + let b = asyncGetOrFail(3, false) + let sum = a.flatMap { a in + b.map { b in + try a() + b() + } + } + + _ = try sum.sync()() + XCTFail() + } catch let error as FooError { + XCTAssertEqual(error.value, 2) + } catch _ { + XCTFail() + } + + do { + let a = asyncGetOrFail(2, false) + let b = asyncGetOrFail(3, true) + let sum = a.flatMap { a in + b.map { b in + try a() + b() + } + } + + _ = try sum.sync()() + XCTFail() + } catch let error as FooError { + XCTAssertEqual(error.value, 3) + } catch _ { + XCTFail() + } + + do { + let a = asyncGetOrFail(2, true) + let b = asyncGetOrFail(3, true) + let sum = a.flatMap { a in + b.map { b in + try a() + b() + } + } + + _ = try sum.sync()() + XCTFail() + } catch let error as FooError { + XCTAssertEqual(error.value, 2) + } catch _ { + XCTFail() + } + + do { + let sum = asyncGetOrFail(2, false).flatMap { getA throws -> Promise in + let a = try getA() + return asyncGet(3).map { b in + a + b + } + } + + XCTAssertEqual(try sum.sync()(), 5) + } + + do { + let sum = asyncGetOrFail(2, true).flatMap { getA throws -> Promise in + let a = try getA() + return asyncGet(3).map { b in + a + b + } + } + + _ = try sum.sync()() + XCTFail() + } catch let error as FooError { + XCTAssertEqual(error.value, 2) + } catch _ { + XCTFail() + } + } + func testSynchronization() { let queue1 = DispatchQueue(label: "foo", attributes: []) let queue2 = DispatchQueue(label: "bar", attributes: []) @@ -70,25 +185,43 @@ class PromiseKTests: XCTestCase { } func testSample() { - // `flatMap` is equivalent to `then` of JavaScript's `Promise` - let a: Promise = asyncGet(2).flatMap { asyncGet($0) }.flatMap { asyncGet($0) } - let b: Promise = asyncGet(3).map { $0 * $0 } - let sum: Promise = a.flatMap { a0 in b.flatMap{ b0 in Promise(a0 + b0) } } - - // uses `Optional` for error handling - let mightFail: Promise = asyncFailable(5).flatMap { Promise($0.map { $0 * $0 }) } - let howToCatch: Promise = asyncFailable(7).flatMap { Promise($0 ?? 0) } - - sum.wait() - print(a) - print(b) - print(sum) - - mightFail.wait() - print(mightFail) - - howToCatch.wait() - print(howToCatch) + do { + // `flatMap` is equivalent to `then` of JavaScript's `Promise` + let a: Promise = asyncGet(2) + let b: Promise = asyncGet(3).map { $0 * $0 } // Promise(9) + let sum: Promise = a.flatMap { a in b.flatMap{ b in Promise(a + b) } } + + sum.wait() + print(a) + print(b) + print(sum) + } + + do { + // Collaborates with `throws` for error handling + let a: Promise<() throws -> Int> = asyncFailable(2) + let b: Promise<() throws -> Int> = asyncFailable(3).map { try $0() * $0() } + let sum: Promise<() throws -> Int> = a.flatMap { a in b.map { b in try a() * b() } } + + sum.wait() + print(a) + print(b) + print(sum) + } + + do { + // Recovery from errors + let recovered: Promise = asyncFailable(42).map { value in + do { + return try value() + } catch _ { + return -1 + } + } + + recovered.wait() + print(recovered) + } } } @@ -104,12 +237,17 @@ func asyncGet(_ value: Int) -> Promise { return async(value) } -func asyncGetOrFail(_ value: Int, _ fails: Bool) -> Promise { - return fails ? Promise(nil) : asyncGet(value).map { $0 } +func asyncGetOrFail(_ value: Int, _ fails: Bool) -> Promise<() throws -> Int> { + return asyncGet(value).map { + if fails { + throw FooError(value: value) + } + return $0 + } } -func asyncFailable(_ value: Int) -> Promise { - return async(value).map { arc4random() % 2 == 0 ? $0 : nil } +func asyncFailable(_ value: Int) -> Promise<() throws -> Int> { + return asyncGetOrFail(value, arc4random() % 2 == 0) } func foo(_ a: Int, _ b: Int) -> (Int, Int) { @@ -120,6 +258,10 @@ func curry(_ f: @escaping (A, B) -> Z) -> (A) -> (B) -> Z { return { a in { b in f(a, b) } } } +struct FooError: Error { + var value: Int +} + extension Promise { func wait() { var finished = false @@ -131,4 +273,13 @@ extension Promise { RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.1)) } } + + func sync() -> Value { + wait() + var value: Value? = nil + _ = map { + value = $0 + } + return value! + } } From 2e2bdfc22794429025ea784f8e2f53c0fc05bf15 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 2 May 2017 17:48:32 +0900 Subject: [PATCH 09/29] Update README --- README.md | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c9285d8..60a7c06 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,32 @@ PromiseK _PromiseK_ provides a simple monadic `Promise` type for Swift. ```swift -// `map` and `flatMap` are equivalent to `then` of JavaScript's `Promise` -let a: Promise = asyncGet(2).flatMap { asyncGet($0) }.flatMap { asyncGet($0) } -let b: Promise = asyncGet(3).map { $0 * $0 } -let sum: Promise = a.flatMap { a0 in b.flatMap { b0 in Promise(a0 + b0) } } +// `flatMap` is equivalent to `then` of JavaScript's `Promise` +let a: Promise = asyncGet(2) +let b: Promise = asyncGet(3).map { $0 * $0 } // Promise(9) +let sum: Promise = a.flatMap { a in b.flatMap{ b in Promise(a + b) } } +``` + +`Promise` can collaborate with `throws` for failable asynchronous operations. + +```swift +// Collaborates with `throws` for error handling +let a: Promise<() throws -> Int> = asyncFailable(2) +let b: Promise<() throws -> Int> = asyncFailable(3).map { try $0() * $0() } +let sum: Promise<() throws -> Int> = a.flatMap { a in b.map { b in try a() * b() } } +``` + +It is also possible to recover from errors. + +```swift +// Recovery from errors +let recovered: Promise = asyncFailable(42).map { value in + do { + return try value() + } catch _ { + return -1 + } +} ``` Installation From 620ba587f30f2877e29244077c1ad498402cff0b Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 2 May 2017 18:17:36 +0900 Subject: [PATCH 10/29] Simplify tests --- Tests/PromiseKTests/PromiseKTests.swift | 53 ++++++++----------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index 36a098e..592cf9b 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -3,45 +3,34 @@ import XCTest class PromiseKTests: XCTestCase { func testMap() { - let expectation = self.expectation(description: "") - - _ = asyncGet(3).map { - XCTAssertEqual($0, 3) - return $0 * $0 - }.map { (value: Int) in - XCTAssertEqual(value, 9) - expectation.fulfill() + let squared = asyncGet(3).map { + $0 * $0 } - waitForExpectations(timeout: 3.0, handler: nil) + XCTAssertEqual(squared.sync(), 9) } func testFlatMap() { do { - let expectation = self.expectation(description: "") - - _ = asyncGet(3).flatMap { value -> Promise<()> in - XCTAssertEqual(value, 3) - expectation.fulfill() - return Promise<()>() + let a = asyncGet(2) + let b = asyncGet(3) + let sum = a.flatMap { a in + b.map { b in + a + b + } } - waitForExpectations(timeout: 3.0, handler: nil) + XCTAssertEqual(sum.sync(), 5) } do { - let expectation = self.expectation(description: "") - - _ = asyncGet(3).flatMap { (value: Int) in - XCTAssertEqual(value, 3) - return asyncGet(value * value) - }.flatMap { (value: Int) -> Promise<()> in - XCTAssertEqual(value, 9) - expectation.fulfill() - return Promise<()>() + let sum = asyncGet(2).flatMap { a in + asyncGet(3).map { b in + a + b + } } - waitForExpectations(timeout: 3.0, handler: nil) + XCTAssertEqual(sum.sync(), 5) } } @@ -168,12 +157,12 @@ class PromiseKTests: XCTestCase { let expectation = self.expectation(description: "\(i)") let promise = Promise { resolve in - queue1.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.01 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { + queue1.asyncAfter(deadline: .now() + 0.01) { resolve(Promise(2)) } } - queue2.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.01 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { + queue2.asyncAfter(deadline: .now() + 0.01) { let _: Promise = promise.flatMap { expectation.fulfill() return Promise($0 * $0) @@ -250,14 +239,6 @@ func asyncFailable(_ value: Int) -> Promise<() throws -> Int> { return asyncGetOrFail(value, arc4random() % 2 == 0) } -func foo(_ a: Int, _ b: Int) -> (Int, Int) { - return (a, b) -} - -func curry(_ f: @escaping (A, B) -> Z) -> (A) -> (B) -> Z { - return { a in { b in f(a, b) } } -} - struct FooError: Error { var value: Int } From dceeda183544365fecea93b274f8df4f51b8fcfc Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 17 Oct 2017 22:54:07 +0900 Subject: [PATCH 11/29] Implement `get` --- Sources/Promise.swift | 4 ++++ Tests/PromiseKTests/PromiseKTests.swift | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Sources/Promise.swift b/Sources/Promise.swift index 3abf327..ae123fb 100644 --- a/Sources/Promise.swift +++ b/Sources/Promise.swift @@ -46,6 +46,10 @@ public class Promise { public func flatMap(_ transform: @escaping (Value) -> Promise) -> Promise { return Promise { resolve in self.reserve { resolve(transform($0)) } } } + + public func get(_ handler: @escaping (Value) -> ()) { + _ = map(handler) + } } extension Promise : CustomStringConvertible { diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index 592cf9b..e0a5bcd 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -34,6 +34,21 @@ class PromiseKTests: XCTestCase { } } + func testGet() { + let expectation = self.expectation(description: "testGet") + + let value = asyncGet(42) + var obtained: Int? = nil + value.get { + obtained = $0 + expectation.fulfill() + } + + waitForExpectations(timeout: 1.0, handler: nil) + + XCTAssertEqual(obtained, .some(42)) + } + func testFailableMap() { do { let squared = asyncGetOrFail(3, false).map { @@ -258,7 +273,7 @@ extension Promise { func sync() -> Value { wait() var value: Value? = nil - _ = map { + get { value = $0 } return value! From 6d6d9deaea11efc5144dce538863e651bb2c596a Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 17 Oct 2017 23:02:46 +0900 Subject: [PATCH 12/29] Update for swift-tools-version:4.0 --- Package.swift | 8 ++++++-- Sources/{ => PromiseK}/Promise.swift | 0 Sources/{ => PromiseK}/Throws.swift | 0 Tests/PromiseKTests/PromiseKTests.swift | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) rename Sources/{ => PromiseK}/Promise.swift (100%) rename Sources/{ => PromiseK}/Throws.swift (100%) diff --git a/Package.swift b/Package.swift index 98ef787..884fe82 100644 --- a/Package.swift +++ b/Package.swift @@ -1,7 +1,11 @@ -// swift-tools-version:3.1 +// swift-tools-version:4.0 import PackageDescription let package = Package( - name: "PromiseK" + name: "PromiseK", + targets: [ + .target(name: "PromiseK", dependencies: []), + .testTarget(name: "PromiseKTests", dependencies: ["PromiseK"]), + ] ) diff --git a/Sources/Promise.swift b/Sources/PromiseK/Promise.swift similarity index 100% rename from Sources/Promise.swift rename to Sources/PromiseK/Promise.swift diff --git a/Sources/Throws.swift b/Sources/PromiseK/Throws.swift similarity index 100% rename from Sources/Throws.swift rename to Sources/PromiseK/Throws.swift diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index e0a5bcd..f982a07 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -263,7 +263,7 @@ extension Promise { var finished = false _ = self.flatMap { (value: Value) -> Promise<()> in finished = true - return Promise<()>() + return Promise<()>(()) } while (!finished){ RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.1)) From 808a64a6cfbba3f1dbc727308f0783256e03d0ac Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 17 Oct 2017 23:16:40 +0900 Subject: [PATCH 13/29] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 60a7c06..c27c3eb 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,9 @@ Installation By Swift Package Manager. ```swift -.Package( +.package( url: "https://github.com/koher/PromiseK.git", - majorVersion: 3 + from: "3.0.0-alpha" ) ``` From d9866a1c6e6b4ed4e253890d17133b82b3c37566 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Tue, 17 Oct 2017 23:27:17 +0900 Subject: [PATCH 14/29] Fix Package.swift --- Package.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Package.swift b/Package.swift index 884fe82..e914018 100644 --- a/Package.swift +++ b/Package.swift @@ -4,6 +4,9 @@ import PackageDescription let package = Package( name: "PromiseK", + products: [ + .library(name: "PromiseK", targets: ["PromiseK"]), + ], targets: [ .target(name: "PromiseK", dependencies: []), .testTarget(name: "PromiseKTests", dependencies: ["PromiseK"]), From b18589963e6a6249ff70a5c6278d92490b779089 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Wed, 18 Oct 2017 16:45:24 +0900 Subject: [PATCH 15/29] Change `resolve` to receive `T` Originally `resolve` had received `Promise`. --- Sources/PromiseK/Promise.swift | 45 +++++++++++++------------ Tests/PromiseKTests/PromiseKTests.swift | 4 +-- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index ae123fb..51f9e18 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -10,41 +10,44 @@ public class Promise { self.value = value } - public init(_ executor: (_ resolve: @escaping (Promise) -> ()) -> ()) { + public init(_ executor: (_ resolve: @escaping (Value) -> ()) -> ()) { executor(resolve) } - private func resolve(_ promise: Promise) { - promise.reserve { - self.lock.lock() - if self.value == nil { - self.value = $0 - - for handler in self.handlers { - handler($0) - } - self.handlers.removeAll(keepingCapacity: false) + private func resolve(_ value: Value) { + lock.lock() + defer { + lock.unlock() + } + if self.value == nil { + self.value = value + + for handler in self.handlers { + handler(value) } - self.lock.unlock() + self.handlers.removeAll(keepingCapacity: false) } } - private func reserve(_ handler: @escaping (Value) -> ()) { + public func map(_ transform: @escaping (Value) -> T) -> Promise { lock.lock() + defer { + lock.unlock() + } + if let value = self.value { - handler(value) + return Promise(transform(value)) } else { - handlers.append(handler) + return Promise { resolve in + handlers.append { value in + resolve(transform(value)) + } + } } - lock.unlock() - } - - public func map(_ transform: @escaping (Value) -> T) -> Promise { - return flatMap { Promise(transform($0)) } } public func flatMap(_ transform: @escaping (Value) -> Promise) -> Promise { - return Promise { resolve in self.reserve { resolve(transform($0)) } } + return Promise { resolve in self.get { transform($0).get { resolve($0) } } } } public func get(_ handler: @escaping (Value) -> ()) { diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index f982a07..4c91b5a 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -173,7 +173,7 @@ class PromiseKTests: XCTestCase { let promise = Promise { resolve in queue1.asyncAfter(deadline: .now() + 0.01) { - resolve(Promise(2)) + resolve(2) } } @@ -232,7 +232,7 @@ class PromiseKTests: XCTestCase { func async(_ value: T) -> Promise { return Promise { resolve in DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - resolve(Promise(value)) + resolve(value) } } } From 59aa144ccb342095793b44c3c0f3a3a1a6fec21d Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Wed, 18 Oct 2017 16:55:24 +0900 Subject: [PATCH 16/29] Rename `resolve` to `fulfill` --- Sources/PromiseK/Promise.swift | 12 ++++++------ Tests/PromiseKTests/PromiseKTests.swift | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index 51f9e18..1f95a5d 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -10,11 +10,11 @@ public class Promise { self.value = value } - public init(_ executor: (_ resolve: @escaping (Value) -> ()) -> ()) { - executor(resolve) + public init(_ executor: (_ fulfill: @escaping (Value) -> ()) -> ()) { + executor(fulfill) } - private func resolve(_ value: Value) { + private func fulfill(_ value: Value) { lock.lock() defer { lock.unlock() @@ -38,16 +38,16 @@ public class Promise { if let value = self.value { return Promise(transform(value)) } else { - return Promise { resolve in + return Promise { fulfill in handlers.append { value in - resolve(transform(value)) + fulfill(transform(value)) } } } } public func flatMap(_ transform: @escaping (Value) -> Promise) -> Promise { - return Promise { resolve in self.get { transform($0).get { resolve($0) } } } + return Promise { fulfill in self.get { transform($0).get { fulfill($0) } } } } public func get(_ handler: @escaping (Value) -> ()) { diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index 4c91b5a..7922c18 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -168,12 +168,12 @@ class PromiseKTests: XCTestCase { let queue1 = DispatchQueue(label: "foo", attributes: []) let queue2 = DispatchQueue(label: "bar", attributes: []) - for i in 1...100 { // cause simultaneous `resolve` and `reserve` + for i in 1...100 { // cause simultaneous `fulfill` and `map` let expectation = self.expectation(description: "\(i)") - let promise = Promise { resolve in + let promise = Promise { fulfill in queue1.asyncAfter(deadline: .now() + 0.01) { - resolve(2) + fulfill(2) } } @@ -230,9 +230,9 @@ class PromiseKTests: XCTestCase { } func async(_ value: T) -> Promise { - return Promise { resolve in + return Promise { fulfill in DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - resolve(value) + fulfill(value) } } } From 38286b95b50ae0eb599160043d47b42695703d96 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Wed, 18 Oct 2017 17:27:48 +0900 Subject: [PATCH 17/29] Move core implementations from `map` to `get` --- Sources/PromiseK/Promise.swift | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index 1f95a5d..d4cfec3 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -30,29 +30,25 @@ public class Promise { } public func map(_ transform: @escaping (Value) -> T) -> Promise { + return Promise { fulfill in get { fulfill(transform($0)) } } + } + + public func flatMap(_ transform: @escaping (Value) -> Promise) -> Promise { + return Promise { fulfill in get { transform($0).get { fulfill($0) } } } + } + + public func get(_ handler: @escaping (Value) -> ()) { lock.lock() defer { lock.unlock() } - + if let value = self.value { - return Promise(transform(value)) + handler(value) } else { - return Promise { fulfill in - handlers.append { value in - fulfill(transform(value)) - } - } + handlers.append(handler) } } - - public func flatMap(_ transform: @escaping (Value) -> Promise) -> Promise { - return Promise { fulfill in self.get { transform($0).get { fulfill($0) } } } - } - - public func get(_ handler: @escaping (Value) -> ()) { - _ = map(handler) - } } extension Promise : CustomStringConvertible { From de7313ed47586ddc37fb1443a05fc66cb3bdbda7 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Wed, 18 Oct 2017 17:31:07 +0900 Subject: [PATCH 18/29] Update README --- README.md | 2 +- Tests/PromiseKTests/PromiseKTests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c27c3eb..f00b41d 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ _PromiseK_ provides a simple monadic `Promise` type for Swift. // `flatMap` is equivalent to `then` of JavaScript's `Promise` let a: Promise = asyncGet(2) let b: Promise = asyncGet(3).map { $0 * $0 } // Promise(9) -let sum: Promise = a.flatMap { a in b.flatMap{ b in Promise(a + b) } } +let sum: Promise = a.flatMap { a in b.map{ b in a + b } } ``` `Promise` can collaborate with `throws` for failable asynchronous operations. diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index 7922c18..d220244 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -193,7 +193,7 @@ class PromiseKTests: XCTestCase { // `flatMap` is equivalent to `then` of JavaScript's `Promise` let a: Promise = asyncGet(2) let b: Promise = asyncGet(3).map { $0 * $0 } // Promise(9) - let sum: Promise = a.flatMap { a in b.flatMap{ b in Promise(a + b) } } + let sum: Promise = a.flatMap { a in b.map{ b in a + b } } sum.wait() print(a) From 1312f2d164125ff1efb9d948b0f905c115fb6256 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Wed, 18 Oct 2017 17:51:05 +0900 Subject: [PATCH 19/29] Minor refactoring --- Sources/PromiseK/Promise.swift | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index d4cfec3..dce279c 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -3,7 +3,7 @@ import Foundation public class Promise { private let lock = NSRecursiveLock() - fileprivate var value: Value? + private var value: Value? private var handlers: [(Value) -> ()] = [] public init(_ value: Value) { @@ -16,9 +16,8 @@ public class Promise { private func fulfill(_ value: Value) { lock.lock() - defer { - lock.unlock() - } + defer { lock.unlock() } + if self.value == nil { self.value = value @@ -39,9 +38,7 @@ public class Promise { public func get(_ handler: @escaping (Value) -> ()) { lock.lock() - defer { - lock.unlock() - } + defer { lock.unlock() } if let value = self.value { handler(value) From 8905cdabf9c986d3f1139cba33122c829c10a9e8 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Wed, 18 Oct 2017 17:52:09 +0900 Subject: [PATCH 20/29] Minor refactoring Reordered methods of `Promise`. --- Sources/PromiseK/Promise.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index dce279c..aceda50 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -28,14 +28,6 @@ public class Promise { } } - public func map(_ transform: @escaping (Value) -> T) -> Promise { - return Promise { fulfill in get { fulfill(transform($0)) } } - } - - public func flatMap(_ transform: @escaping (Value) -> Promise) -> Promise { - return Promise { fulfill in get { transform($0).get { fulfill($0) } } } - } - public func get(_ handler: @escaping (Value) -> ()) { lock.lock() defer { lock.unlock() } @@ -46,6 +38,14 @@ public class Promise { handlers.append(handler) } } + + public func map(_ transform: @escaping (Value) -> T) -> Promise { + return Promise { fulfill in get { fulfill(transform($0)) } } + } + + public func flatMap(_ transform: @escaping (Value) -> Promise) -> Promise { + return Promise { fulfill in get { transform($0).get { fulfill($0) } } } + } } extension Promise : CustomStringConvertible { From 5054817cc51ec242e8cb46779169cff8818c8904 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Wed, 18 Oct 2017 17:56:55 +0900 Subject: [PATCH 21/29] Update `description` for unfulfilled `Promise` --- Sources/PromiseK/Promise.swift | 2 +- Tests/PromiseKTests/PromiseKTests.swift | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index aceda50..28235b4 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -53,7 +53,7 @@ extension Promise : CustomStringConvertible { if let value = self.value { return "Promise(\(value))" } else { - return "Promise" + return "Promise(\(Value.self))" } } } diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index d220244..3b98c40 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -49,6 +49,11 @@ class PromiseKTests: XCTestCase { XCTAssertEqual(obtained, .some(42)) } + func testDescription() { + XCTAssertEqual(Promise(42).description, "Promise(42)") + XCTAssertEqual(Promise { _ in }.description, "Promise(Int)") + } + func testFailableMap() { do { let squared = asyncGetOrFail(3, false).map { From 3b9a9c220b6e66d818f39f6039cc19afc7ad3d2b Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Wed, 18 Oct 2017 18:03:34 +0900 Subject: [PATCH 22/29] Minor change Inserted a space before a closure expression. --- README.md | 2 +- Tests/PromiseKTests/PromiseKTests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f00b41d..79c6592 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ _PromiseK_ provides a simple monadic `Promise` type for Swift. // `flatMap` is equivalent to `then` of JavaScript's `Promise` let a: Promise = asyncGet(2) let b: Promise = asyncGet(3).map { $0 * $0 } // Promise(9) -let sum: Promise = a.flatMap { a in b.map{ b in a + b } } +let sum: Promise = a.flatMap { a in b.map { b in a + b } } ``` `Promise` can collaborate with `throws` for failable asynchronous operations. diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index 3b98c40..aae9b06 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -198,7 +198,7 @@ class PromiseKTests: XCTestCase { // `flatMap` is equivalent to `then` of JavaScript's `Promise` let a: Promise = asyncGet(2) let b: Promise = asyncGet(3).map { $0 * $0 } // Promise(9) - let sum: Promise = a.flatMap { a in b.map{ b in a + b } } + let sum: Promise = a.flatMap { a in b.map { b in a + b } } sum.wait() print(a) From 61c50d960956c574204d53979cc59520c661391d Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Thu, 19 Oct 2017 00:29:46 +0900 Subject: [PATCH 23/29] Minor refactoring - Removed unnecessary `self`. - Replace a `for` loop with `forEach` to simplify code. --- Sources/PromiseK/Promise.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index 28235b4..aa52214 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -21,10 +21,8 @@ public class Promise { if self.value == nil { self.value = value - for handler in self.handlers { - handler(value) - } - self.handlers.removeAll(keepingCapacity: false) + handlers.forEach { $0(value) } + handlers.removeAll(keepingCapacity: false) } } From b4b7a074a18c93fa714fd2eb3af94e15199d5750 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Thu, 19 Oct 2017 00:33:54 +0900 Subject: [PATCH 24/29] Forbid to call `fulfill` multiple times --- Sources/PromiseK/Promise.swift | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index aa52214..6048c08 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -18,12 +18,11 @@ public class Promise { lock.lock() defer { lock.unlock() } - if self.value == nil { - self.value = value - - handlers.forEach { $0(value) } - handlers.removeAll(keepingCapacity: false) - } + precondition(self.value == nil, "`fulfill` cannot be called multiple times.") + + self.value = value + handlers.forEach { $0(value) } + handlers.removeAll(keepingCapacity: false) } public func get(_ handler: @escaping (Value) -> ()) { From 64de3913132e3928d8550518d786773b57344d2b Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Thu, 19 Oct 2017 00:57:24 +0900 Subject: [PATCH 25/29] Change `fulfill` to a closure expression --- Sources/PromiseK/Promise.swift | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index 6048c08..03a591a 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -11,18 +11,16 @@ public class Promise { } public init(_ executor: (_ fulfill: @escaping (Value) -> ()) -> ()) { - executor(fulfill) - } - - private func fulfill(_ value: Value) { - lock.lock() - defer { lock.unlock() } - - precondition(self.value == nil, "`fulfill` cannot be called multiple times.") - - self.value = value - handlers.forEach { $0(value) } - handlers.removeAll(keepingCapacity: false) + executor { value in + self.lock.lock() + defer { self.lock.unlock() } + + precondition(self.value == nil, "`fulfill` cannot be called multiple times.") + + self.value = value + self.handlers.forEach { $0(value) } + self.handlers.removeAll(keepingCapacity: false) + } } public func get(_ handler: @escaping (Value) -> ()) { From 945f07fb93ccc28ccaac9e2c150305c82380ad88 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Thu, 19 Oct 2017 00:59:49 +0900 Subject: [PATCH 26/29] Introduce `synchronized` --- Sources/PromiseK/Promise.swift | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index 03a591a..51b856e 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -12,25 +12,22 @@ public class Promise { public init(_ executor: (_ fulfill: @escaping (Value) -> ()) -> ()) { executor { value in - self.lock.lock() - defer { self.lock.unlock() } - - precondition(self.value == nil, "`fulfill` cannot be called multiple times.") - - self.value = value - self.handlers.forEach { $0(value) } - self.handlers.removeAll(keepingCapacity: false) + synchronized(with: self.lock) { + precondition(self.value == nil, "`fulfill` cannot be called multiple times.") + self.value = value + self.handlers.forEach { $0(value) } + self.handlers.removeAll(keepingCapacity: false) + } } } public func get(_ handler: @escaping (Value) -> ()) { - lock.lock() - defer { lock.unlock() } - - if let value = self.value { - handler(value) - } else { - handlers.append(handler) + synchronized(with: lock) { + if let value = self.value { + handler(value) + } else { + handlers.append(handler) + } } } @@ -52,3 +49,9 @@ extension Promise : CustomStringConvertible { } } } + +private func synchronized(with lock: NSRecursiveLock, _ operation: () -> ()) { + lock.lock() + defer { lock.unlock() } + operation() +} From 8c339c6a27b5b834dec65a66e790d736c3739c9a Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Thu, 19 Oct 2017 01:01:59 +0900 Subject: [PATCH 27/29] Reorder the properties of `Promise` --- Sources/PromiseK/Promise.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/PromiseK/Promise.swift b/Sources/PromiseK/Promise.swift index 51b856e..1504935 100644 --- a/Sources/PromiseK/Promise.swift +++ b/Sources/PromiseK/Promise.swift @@ -1,10 +1,9 @@ import Foundation public class Promise { - private let lock = NSRecursiveLock() - private var value: Value? private var handlers: [(Value) -> ()] = [] + private let lock = NSRecursiveLock() public init(_ value: Value) { self.value = value From 4af4397063ed09242b4990ec2034fed1b744ac87 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Fri, 10 Nov 2017 00:48:41 +0900 Subject: [PATCH 28/29] Add the xcodeproj for iOS It can be installed by Carthage. --- .gitignore | 4 +- PromiseK.xcodeproj/project.pbxproj | 465 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcschemes/PromiseK-iOS.xcscheme | 101 ++++ Sources/PromiseK/Info.plist | 24 + Sources/PromiseK/PromiseK.h | 11 + Tests/PromiseKTests/Info.plist | 22 + 7 files changed, 633 insertions(+), 1 deletion(-) create mode 100644 PromiseK.xcodeproj/project.pbxproj create mode 100644 PromiseK.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK-iOS.xcscheme create mode 100644 Sources/PromiseK/Info.plist create mode 100644 Sources/PromiseK/PromiseK.h create mode 100644 Tests/PromiseKTests/Info.plist diff --git a/.gitignore b/.gitignore index 02c0875..17624ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .DS_Store /.build /Packages -/*.xcodeproj +/*.xcodeproj/project.xcworkspace/xcuserdata +/*.xcodeproj/xcuserdata +/Carthage diff --git a/PromiseK.xcodeproj/project.pbxproj b/PromiseK.xcodeproj/project.pbxproj new file mode 100644 index 0000000..7fec3f9 --- /dev/null +++ b/PromiseK.xcodeproj/project.pbxproj @@ -0,0 +1,465 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + D62C6CAB1FB4AE6A00E7DF02 /* PromiseK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D62C6CA21FB4AE6900E7DF02 /* PromiseK.framework */; }; + D62C6CB91FB4AF1B00E7DF02 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62C6C8E1FB4AD0100E7DF02 /* Promise.swift */; }; + D62C6CBB1FB4AF1B00E7DF02 /* Throws.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62C6C901FB4AD0100E7DF02 /* Throws.swift */; }; + D62C6CBC1FB4AF7D00E7DF02 /* PromiseKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62C6C991FB4AD2900E7DF02 /* PromiseKTests.swift */; }; + D62C6CBD1FB4AFE200E7DF02 /* PromiseK.h in Headers */ = {isa = PBXBuildFile; fileRef = D62C6C8F1FB4AD0100E7DF02 /* PromiseK.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + D62C6CAC1FB4AE6A00E7DF02 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D62C6C681FB4AC9100E7DF02 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D62C6CA11FB4AE6900E7DF02; + remoteInfo = "PromiseK-iOS"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + D62C6C8D1FB4AD0100E7DF02 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D62C6C8E1FB4AD0100E7DF02 /* Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Promise.swift; sourceTree = ""; }; + D62C6C8F1FB4AD0100E7DF02 /* PromiseK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PromiseK.h; sourceTree = ""; }; + D62C6C901FB4AD0100E7DF02 /* Throws.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Throws.swift; sourceTree = ""; }; + D62C6C961FB4AD2900E7DF02 /* LinuxMain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinuxMain.swift; sourceTree = ""; }; + D62C6C981FB4AD2900E7DF02 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D62C6C991FB4AD2900E7DF02 /* PromiseKTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PromiseKTests.swift; sourceTree = ""; }; + D62C6CA21FB4AE6900E7DF02 /* PromiseK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PromiseK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D62C6CAA1FB4AE6900E7DF02 /* PromiseKTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PromiseKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D62C6C9E1FB4AE6900E7DF02 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D62C6CA71FB4AE6900E7DF02 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D62C6CAB1FB4AE6A00E7DF02 /* PromiseK.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D62C6C671FB4AC9100E7DF02 = { + isa = PBXGroup; + children = ( + D62C6C8B1FB4AD0100E7DF02 /* Sources */, + D62C6C951FB4AD2900E7DF02 /* Tests */, + D62C6C721FB4AC9100E7DF02 /* Products */, + ); + sourceTree = ""; + }; + D62C6C721FB4AC9100E7DF02 /* Products */ = { + isa = PBXGroup; + children = ( + D62C6CA21FB4AE6900E7DF02 /* PromiseK.framework */, + D62C6CAA1FB4AE6900E7DF02 /* PromiseKTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + D62C6C8B1FB4AD0100E7DF02 /* Sources */ = { + isa = PBXGroup; + children = ( + D62C6C8C1FB4AD0100E7DF02 /* PromiseK */, + ); + path = Sources; + sourceTree = ""; + }; + D62C6C8C1FB4AD0100E7DF02 /* PromiseK */ = { + isa = PBXGroup; + children = ( + D62C6C8D1FB4AD0100E7DF02 /* Info.plist */, + D62C6C8E1FB4AD0100E7DF02 /* Promise.swift */, + D62C6C8F1FB4AD0100E7DF02 /* PromiseK.h */, + D62C6C901FB4AD0100E7DF02 /* Throws.swift */, + ); + path = PromiseK; + sourceTree = ""; + }; + D62C6C951FB4AD2900E7DF02 /* Tests */ = { + isa = PBXGroup; + children = ( + D62C6C961FB4AD2900E7DF02 /* LinuxMain.swift */, + D62C6C971FB4AD2900E7DF02 /* PromiseKTests */, + ); + path = Tests; + sourceTree = ""; + }; + D62C6C971FB4AD2900E7DF02 /* PromiseKTests */ = { + isa = PBXGroup; + children = ( + D62C6C981FB4AD2900E7DF02 /* Info.plist */, + D62C6C991FB4AD2900E7DF02 /* PromiseKTests.swift */, + ); + path = PromiseKTests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D62C6C9F1FB4AE6900E7DF02 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D62C6CBD1FB4AFE200E7DF02 /* PromiseK.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D62C6CA11FB4AE6900E7DF02 /* PromiseK-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D62C6CB31FB4AE6A00E7DF02 /* Build configuration list for PBXNativeTarget "PromiseK-iOS" */; + buildPhases = ( + D62C6C9D1FB4AE6900E7DF02 /* Sources */, + D62C6C9E1FB4AE6900E7DF02 /* Frameworks */, + D62C6C9F1FB4AE6900E7DF02 /* Headers */, + D62C6CA01FB4AE6900E7DF02 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "PromiseK-iOS"; + productName = "PromiseK-iOS"; + productReference = D62C6CA21FB4AE6900E7DF02 /* PromiseK.framework */; + productType = "com.apple.product-type.framework"; + }; + D62C6CA91FB4AE6900E7DF02 /* PromiseKTests-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D62C6CB61FB4AE6A00E7DF02 /* Build configuration list for PBXNativeTarget "PromiseKTests-iOS" */; + buildPhases = ( + D62C6CA61FB4AE6900E7DF02 /* Sources */, + D62C6CA71FB4AE6900E7DF02 /* Frameworks */, + D62C6CA81FB4AE6900E7DF02 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D62C6CAD1FB4AE6A00E7DF02 /* PBXTargetDependency */, + ); + name = "PromiseKTests-iOS"; + productName = "PromiseK-iOSTests"; + productReference = D62C6CAA1FB4AE6900E7DF02 /* PromiseKTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D62C6C681FB4AC9100E7DF02 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0910; + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = koherent.org; + TargetAttributes = { + D62C6CA11FB4AE6900E7DF02 = { + CreatedOnToolsVersion = 9.1; + ProvisioningStyle = Automatic; + }; + D62C6CA91FB4AE6900E7DF02 = { + CreatedOnToolsVersion = 9.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = D62C6C6B1FB4AC9100E7DF02 /* Build configuration list for PBXProject "PromiseK" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D62C6C671FB4AC9100E7DF02; + productRefGroup = D62C6C721FB4AC9100E7DF02 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D62C6CA11FB4AE6900E7DF02 /* PromiseK-iOS */, + D62C6CA91FB4AE6900E7DF02 /* PromiseKTests-iOS */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D62C6CA01FB4AE6900E7DF02 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D62C6CA81FB4AE6900E7DF02 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D62C6C9D1FB4AE6900E7DF02 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D62C6CBB1FB4AF1B00E7DF02 /* Throws.swift in Sources */, + D62C6CB91FB4AF1B00E7DF02 /* Promise.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D62C6CA61FB4AE6900E7DF02 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D62C6CBC1FB4AF7D00E7DF02 /* PromiseKTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + D62C6CAD1FB4AE6A00E7DF02 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D62C6CA11FB4AE6900E7DF02 /* PromiseK-iOS */; + targetProxy = D62C6CAC1FB4AE6A00E7DF02 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + D62C6C831FB4AC9100E7DF02 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + D62C6C841FB4AC9100E7DF02 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + D62C6CB41FB4AE6A00E7DF02 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Sources/PromiseK/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = org.koherent.PromiseK; + PRODUCT_NAME = PromiseK; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + D62C6CB51FB4AE6A00E7DF02 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Sources/PromiseK/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = org.koherent.PromiseK; + PRODUCT_NAME = PromiseK; + SKIP_INSTALL = YES; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + D62C6CB71FB4AE6A00E7DF02 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = Tests/PromiseKTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = org.koherent.PromiseKTests; + PRODUCT_NAME = PromiseKTests; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + D62C6CB81FB4AE6A00E7DF02 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = Tests/PromiseKTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = org.koherent.PromiseKTests; + PRODUCT_NAME = PromiseKTests; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D62C6C6B1FB4AC9100E7DF02 /* Build configuration list for PBXProject "PromiseK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D62C6C831FB4AC9100E7DF02 /* Debug */, + D62C6C841FB4AC9100E7DF02 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D62C6CB31FB4AE6A00E7DF02 /* Build configuration list for PBXNativeTarget "PromiseK-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D62C6CB41FB4AE6A00E7DF02 /* Debug */, + D62C6CB51FB4AE6A00E7DF02 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D62C6CB61FB4AE6A00E7DF02 /* Build configuration list for PBXNativeTarget "PromiseKTests-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D62C6CB71FB4AE6A00E7DF02 /* Debug */, + D62C6CB81FB4AE6A00E7DF02 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D62C6C681FB4AC9100E7DF02 /* Project object */; +} diff --git a/PromiseK.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/PromiseK.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..b865388 --- /dev/null +++ b/PromiseK.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK-iOS.xcscheme b/PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK-iOS.xcscheme new file mode 100644 index 0000000..c07b23f --- /dev/null +++ b/PromiseK.xcodeproj/xcshareddata/xcschemes/PromiseK-iOS.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sources/PromiseK/Info.plist b/Sources/PromiseK/Info.plist new file mode 100644 index 0000000..1007fd9 --- /dev/null +++ b/Sources/PromiseK/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Sources/PromiseK/PromiseK.h b/Sources/PromiseK/PromiseK.h new file mode 100644 index 0000000..19f566d --- /dev/null +++ b/Sources/PromiseK/PromiseK.h @@ -0,0 +1,11 @@ +#import + +//! Project version number for PromiseK. +FOUNDATION_EXPORT double PromiseKVersionNumber; + +//! Project version string for PromiseK. +FOUNDATION_EXPORT const unsigned char PromiseKVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Tests/PromiseKTests/Info.plist b/Tests/PromiseKTests/Info.plist new file mode 100644 index 0000000..6c40a6c --- /dev/null +++ b/Tests/PromiseKTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + From 7964e06216c715b1eb58daca8858634f49bb0373 Mon Sep 17 00:00:00 2001 From: Yuta Koshizawa Date: Thu, 28 Dec 2017 01:57:10 +0900 Subject: [PATCH 29/29] Implement `testKeepingFulfill` --- Tests/PromiseKTests/PromiseKTests.swift | 40 +++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Tests/PromiseKTests/PromiseKTests.swift b/Tests/PromiseKTests/PromiseKTests.swift index aae9b06..c1274a9 100644 --- a/Tests/PromiseKTests/PromiseKTests.swift +++ b/Tests/PromiseKTests/PromiseKTests.swift @@ -193,6 +193,46 @@ class PromiseKTests: XCTestCase { } } + func testKeepingFulfill() { + do { + var fulfill: ((Int) -> ())! + let a = Promise { + fulfill = $0 + } + fulfill(42) + XCTAssertEqual(a.sync(), 42) + } + + do { + var fulfill: ((@escaping () throws -> Int) -> ())! + let a = Promise<() throws -> Int> { + fulfill = $0 + } + fulfill { 42 } + XCTAssertEqual(try! a.sync()(), 42) + } + + do { + let queue = DispatchQueue(label: "foo", attributes: []) + + var fulfill: ((@escaping () throws -> Int) -> ())! + let a = Promise<() throws -> Int> { + fulfill = $0 + } + + let expectation = self.expectation(description: "testKeepingFulfill") + + queue.asyncAfter(deadline: .now() + 0.01) { + fulfill { 42 } + expectation.fulfill() + } + + waitForExpectations(timeout: 3.0, handler: nil) + + XCTAssertEqual(try! a.sync()(), 42) + } + } + func testSample() { do { // `flatMap` is equivalent to `then` of JavaScript's `Promise`