├── .gitignore ├── LICENSE ├── NonEmptyArray.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── NonEmptyArray ├── Info.plist ├── NonEmptyArray.h └── NonEmptyArray.swift ├── NonEmptyArrayTests ├── AppendingTests.swift ├── ComparableTests.swift ├── EqualityTests.swift ├── Info.plist ├── NonComparableTests.swift ├── NonEmptyArrayTests.swift └── RemovalTests.swift └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Soroush Khanlou 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NonEmptyArray.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 340D5F1F1DB44A6400966200 /* NonComparableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340D5F1E1DB44A6400966200 /* NonComparableTests.swift */; }; 11 | 340D5F211DB44B8600966200 /* AppendingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340D5F201DB44B8600966200 /* AppendingTests.swift */; }; 12 | 340D5F231DB44C1900966200 /* EqualityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340D5F221DB44C1900966200 /* EqualityTests.swift */; }; 13 | 340D5F251DB44DCB00966200 /* ComparableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340D5F241DB44DCB00966200 /* ComparableTests.swift */; }; 14 | 340D5F271DB45E2500966200 /* RemovalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340D5F261DB45E2500966200 /* RemovalTests.swift */; }; 15 | 340EEEB31DB2F4A3003BE19E /* NonEmptyArray.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 340EEEA91DB2F4A3003BE19E /* NonEmptyArray.framework */; }; 16 | 340EEEB81DB2F4A3003BE19E /* NonEmptyArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340EEEB71DB2F4A3003BE19E /* NonEmptyArrayTests.swift */; }; 17 | 340EEEBA1DB2F4A3003BE19E /* NonEmptyArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 340EEEAC1DB2F4A3003BE19E /* NonEmptyArray.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18 | 340EEEC41DB2F4BF003BE19E /* NonEmptyArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340EEEC31DB2F4BF003BE19E /* NonEmptyArray.swift */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 340EEEB41DB2F4A3003BE19E /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 340EEEA01DB2F4A2003BE19E /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = 340EEEA81DB2F4A3003BE19E; 27 | remoteInfo = NonEmptyArray; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 340D5F1E1DB44A6400966200 /* NonComparableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NonComparableTests.swift; sourceTree = ""; }; 33 | 340D5F201DB44B8600966200 /* AppendingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppendingTests.swift; sourceTree = ""; }; 34 | 340D5F221DB44C1900966200 /* EqualityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EqualityTests.swift; sourceTree = ""; }; 35 | 340D5F241DB44DCB00966200 /* ComparableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComparableTests.swift; sourceTree = ""; }; 36 | 340D5F261DB45E2500966200 /* RemovalTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemovalTests.swift; sourceTree = ""; }; 37 | 340EEEA91DB2F4A3003BE19E /* NonEmptyArray.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NonEmptyArray.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 340EEEAC1DB2F4A3003BE19E /* NonEmptyArray.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NonEmptyArray.h; sourceTree = ""; }; 39 | 340EEEAD1DB2F4A3003BE19E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 40 | 340EEEB21DB2F4A3003BE19E /* NonEmptyArrayTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NonEmptyArrayTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 340EEEB71DB2F4A3003BE19E /* NonEmptyArrayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonEmptyArrayTests.swift; sourceTree = ""; }; 42 | 340EEEB91DB2F4A3003BE19E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | 340EEEC31DB2F4BF003BE19E /* NonEmptyArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NonEmptyArray.swift; sourceTree = ""; }; 44 | /* End PBXFileReference section */ 45 | 46 | /* Begin PBXFrameworksBuildPhase section */ 47 | 340EEEA51DB2F4A3003BE19E /* Frameworks */ = { 48 | isa = PBXFrameworksBuildPhase; 49 | buildActionMask = 2147483647; 50 | files = ( 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | 340EEEAF1DB2F4A3003BE19E /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | 340EEEB31DB2F4A3003BE19E /* NonEmptyArray.framework in Frameworks */, 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | 340EEE9F1DB2F4A2003BE19E = { 66 | isa = PBXGroup; 67 | children = ( 68 | 340EEEAB1DB2F4A3003BE19E /* NonEmptyArray */, 69 | 340EEEB61DB2F4A3003BE19E /* NonEmptyArrayTests */, 70 | 340EEEAA1DB2F4A3003BE19E /* Products */, 71 | ); 72 | sourceTree = ""; 73 | }; 74 | 340EEEAA1DB2F4A3003BE19E /* Products */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 340EEEA91DB2F4A3003BE19E /* NonEmptyArray.framework */, 78 | 340EEEB21DB2F4A3003BE19E /* NonEmptyArrayTests.xctest */, 79 | ); 80 | name = Products; 81 | sourceTree = ""; 82 | }; 83 | 340EEEAB1DB2F4A3003BE19E /* NonEmptyArray */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 340EEEAC1DB2F4A3003BE19E /* NonEmptyArray.h */, 87 | 340EEEAD1DB2F4A3003BE19E /* Info.plist */, 88 | 340EEEC31DB2F4BF003BE19E /* NonEmptyArray.swift */, 89 | ); 90 | path = NonEmptyArray; 91 | sourceTree = ""; 92 | }; 93 | 340EEEB61DB2F4A3003BE19E /* NonEmptyArrayTests */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 340EEEB71DB2F4A3003BE19E /* NonEmptyArrayTests.swift */, 97 | 340D5F241DB44DCB00966200 /* ComparableTests.swift */, 98 | 340D5F1E1DB44A6400966200 /* NonComparableTests.swift */, 99 | 340D5F201DB44B8600966200 /* AppendingTests.swift */, 100 | 340D5F261DB45E2500966200 /* RemovalTests.swift */, 101 | 340D5F221DB44C1900966200 /* EqualityTests.swift */, 102 | 340EEEB91DB2F4A3003BE19E /* Info.plist */, 103 | ); 104 | path = NonEmptyArrayTests; 105 | sourceTree = ""; 106 | }; 107 | /* End PBXGroup section */ 108 | 109 | /* Begin PBXHeadersBuildPhase section */ 110 | 340EEEA61DB2F4A3003BE19E /* Headers */ = { 111 | isa = PBXHeadersBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | 340EEEBA1DB2F4A3003BE19E /* NonEmptyArray.h in Headers */, 115 | ); 116 | runOnlyForDeploymentPostprocessing = 0; 117 | }; 118 | /* End PBXHeadersBuildPhase section */ 119 | 120 | /* Begin PBXNativeTarget section */ 121 | 340EEEA81DB2F4A3003BE19E /* NonEmptyArray */ = { 122 | isa = PBXNativeTarget; 123 | buildConfigurationList = 340EEEBD1DB2F4A3003BE19E /* Build configuration list for PBXNativeTarget "NonEmptyArray" */; 124 | buildPhases = ( 125 | 340EEEA41DB2F4A3003BE19E /* Sources */, 126 | 340EEEA51DB2F4A3003BE19E /* Frameworks */, 127 | 340EEEA61DB2F4A3003BE19E /* Headers */, 128 | 340EEEA71DB2F4A3003BE19E /* Resources */, 129 | ); 130 | buildRules = ( 131 | ); 132 | dependencies = ( 133 | ); 134 | name = NonEmptyArray; 135 | productName = NonEmptyArray; 136 | productReference = 340EEEA91DB2F4A3003BE19E /* NonEmptyArray.framework */; 137 | productType = "com.apple.product-type.framework"; 138 | }; 139 | 340EEEB11DB2F4A3003BE19E /* NonEmptyArrayTests */ = { 140 | isa = PBXNativeTarget; 141 | buildConfigurationList = 340EEEC01DB2F4A3003BE19E /* Build configuration list for PBXNativeTarget "NonEmptyArrayTests" */; 142 | buildPhases = ( 143 | 340EEEAE1DB2F4A3003BE19E /* Sources */, 144 | 340EEEAF1DB2F4A3003BE19E /* Frameworks */, 145 | 340EEEB01DB2F4A3003BE19E /* Resources */, 146 | ); 147 | buildRules = ( 148 | ); 149 | dependencies = ( 150 | 340EEEB51DB2F4A3003BE19E /* PBXTargetDependency */, 151 | ); 152 | name = NonEmptyArrayTests; 153 | productName = NonEmptyArrayTests; 154 | productReference = 340EEEB21DB2F4A3003BE19E /* NonEmptyArrayTests.xctest */; 155 | productType = "com.apple.product-type.bundle.unit-test"; 156 | }; 157 | /* End PBXNativeTarget section */ 158 | 159 | /* Begin PBXProject section */ 160 | 340EEEA01DB2F4A2003BE19E /* Project object */ = { 161 | isa = PBXProject; 162 | attributes = { 163 | LastSwiftUpdateCheck = 0800; 164 | LastUpgradeCheck = 0800; 165 | ORGANIZATIONNAME = "Soroush Khanlou"; 166 | TargetAttributes = { 167 | 340EEEA81DB2F4A3003BE19E = { 168 | CreatedOnToolsVersion = 8.0; 169 | LastSwiftMigration = 0800; 170 | ProvisioningStyle = Automatic; 171 | }; 172 | 340EEEB11DB2F4A3003BE19E = { 173 | CreatedOnToolsVersion = 8.0; 174 | ProvisioningStyle = Automatic; 175 | }; 176 | }; 177 | }; 178 | buildConfigurationList = 340EEEA31DB2F4A2003BE19E /* Build configuration list for PBXProject "NonEmptyArray" */; 179 | compatibilityVersion = "Xcode 3.2"; 180 | developmentRegion = English; 181 | hasScannedForEncodings = 0; 182 | knownRegions = ( 183 | en, 184 | ); 185 | mainGroup = 340EEE9F1DB2F4A2003BE19E; 186 | productRefGroup = 340EEEAA1DB2F4A3003BE19E /* Products */; 187 | projectDirPath = ""; 188 | projectRoot = ""; 189 | targets = ( 190 | 340EEEA81DB2F4A3003BE19E /* NonEmptyArray */, 191 | 340EEEB11DB2F4A3003BE19E /* NonEmptyArrayTests */, 192 | ); 193 | }; 194 | /* End PBXProject section */ 195 | 196 | /* Begin PBXResourcesBuildPhase section */ 197 | 340EEEA71DB2F4A3003BE19E /* Resources */ = { 198 | isa = PBXResourcesBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | 340EEEB01DB2F4A3003BE19E /* Resources */ = { 205 | isa = PBXResourcesBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | /* End PBXResourcesBuildPhase section */ 212 | 213 | /* Begin PBXSourcesBuildPhase section */ 214 | 340EEEA41DB2F4A3003BE19E /* Sources */ = { 215 | isa = PBXSourcesBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | 340EEEC41DB2F4BF003BE19E /* NonEmptyArray.swift in Sources */, 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | }; 222 | 340EEEAE1DB2F4A3003BE19E /* Sources */ = { 223 | isa = PBXSourcesBuildPhase; 224 | buildActionMask = 2147483647; 225 | files = ( 226 | 340D5F271DB45E2500966200 /* RemovalTests.swift in Sources */, 227 | 340EEEB81DB2F4A3003BE19E /* NonEmptyArrayTests.swift in Sources */, 228 | 340D5F251DB44DCB00966200 /* ComparableTests.swift in Sources */, 229 | 340D5F211DB44B8600966200 /* AppendingTests.swift in Sources */, 230 | 340D5F1F1DB44A6400966200 /* NonComparableTests.swift in Sources */, 231 | 340D5F231DB44C1900966200 /* EqualityTests.swift in Sources */, 232 | ); 233 | runOnlyForDeploymentPostprocessing = 0; 234 | }; 235 | /* End PBXSourcesBuildPhase section */ 236 | 237 | /* Begin PBXTargetDependency section */ 238 | 340EEEB51DB2F4A3003BE19E /* PBXTargetDependency */ = { 239 | isa = PBXTargetDependency; 240 | target = 340EEEA81DB2F4A3003BE19E /* NonEmptyArray */; 241 | targetProxy = 340EEEB41DB2F4A3003BE19E /* PBXContainerItemProxy */; 242 | }; 243 | /* End PBXTargetDependency section */ 244 | 245 | /* Begin XCBuildConfiguration section */ 246 | 340EEEBB1DB2F4A3003BE19E /* Debug */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | ALWAYS_SEARCH_USER_PATHS = NO; 250 | CLANG_ANALYZER_NONNULL = YES; 251 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 252 | CLANG_CXX_LIBRARY = "libc++"; 253 | CLANG_ENABLE_MODULES = YES; 254 | CLANG_ENABLE_OBJC_ARC = YES; 255 | CLANG_WARN_BOOL_CONVERSION = YES; 256 | CLANG_WARN_CONSTANT_CONVERSION = YES; 257 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 258 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 259 | CLANG_WARN_EMPTY_BODY = YES; 260 | CLANG_WARN_ENUM_CONVERSION = YES; 261 | CLANG_WARN_INFINITE_RECURSION = YES; 262 | CLANG_WARN_INT_CONVERSION = YES; 263 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 264 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 265 | CLANG_WARN_UNREACHABLE_CODE = YES; 266 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 267 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 268 | COPY_PHASE_STRIP = NO; 269 | CURRENT_PROJECT_VERSION = 1; 270 | DEBUG_INFORMATION_FORMAT = dwarf; 271 | ENABLE_STRICT_OBJC_MSGSEND = YES; 272 | ENABLE_TESTABILITY = YES; 273 | GCC_C_LANGUAGE_STANDARD = gnu99; 274 | GCC_DYNAMIC_NO_PIC = NO; 275 | GCC_NO_COMMON_BLOCKS = YES; 276 | GCC_OPTIMIZATION_LEVEL = 0; 277 | GCC_PREPROCESSOR_DEFINITIONS = ( 278 | "DEBUG=1", 279 | "$(inherited)", 280 | ); 281 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 282 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 283 | GCC_WARN_UNDECLARED_SELECTOR = YES; 284 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 285 | GCC_WARN_UNUSED_FUNCTION = YES; 286 | GCC_WARN_UNUSED_VARIABLE = YES; 287 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 288 | MTL_ENABLE_DEBUG_INFO = YES; 289 | ONLY_ACTIVE_ARCH = YES; 290 | SDKROOT = iphoneos; 291 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 292 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 293 | TARGETED_DEVICE_FAMILY = "1,2"; 294 | VERSIONING_SYSTEM = "apple-generic"; 295 | VERSION_INFO_PREFIX = ""; 296 | }; 297 | name = Debug; 298 | }; 299 | 340EEEBC1DB2F4A3003BE19E /* Release */ = { 300 | isa = XCBuildConfiguration; 301 | buildSettings = { 302 | ALWAYS_SEARCH_USER_PATHS = NO; 303 | CLANG_ANALYZER_NONNULL = YES; 304 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 305 | CLANG_CXX_LIBRARY = "libc++"; 306 | CLANG_ENABLE_MODULES = YES; 307 | CLANG_ENABLE_OBJC_ARC = YES; 308 | CLANG_WARN_BOOL_CONVERSION = YES; 309 | CLANG_WARN_CONSTANT_CONVERSION = YES; 310 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 311 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 312 | CLANG_WARN_EMPTY_BODY = YES; 313 | CLANG_WARN_ENUM_CONVERSION = YES; 314 | CLANG_WARN_INFINITE_RECURSION = YES; 315 | CLANG_WARN_INT_CONVERSION = YES; 316 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 317 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 318 | CLANG_WARN_UNREACHABLE_CODE = YES; 319 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 320 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 321 | COPY_PHASE_STRIP = NO; 322 | CURRENT_PROJECT_VERSION = 1; 323 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 324 | ENABLE_NS_ASSERTIONS = NO; 325 | ENABLE_STRICT_OBJC_MSGSEND = YES; 326 | GCC_C_LANGUAGE_STANDARD = gnu99; 327 | GCC_NO_COMMON_BLOCKS = YES; 328 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 329 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 330 | GCC_WARN_UNDECLARED_SELECTOR = YES; 331 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 332 | GCC_WARN_UNUSED_FUNCTION = YES; 333 | GCC_WARN_UNUSED_VARIABLE = YES; 334 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 335 | MTL_ENABLE_DEBUG_INFO = NO; 336 | SDKROOT = iphoneos; 337 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 338 | TARGETED_DEVICE_FAMILY = "1,2"; 339 | VALIDATE_PRODUCT = YES; 340 | VERSIONING_SYSTEM = "apple-generic"; 341 | VERSION_INFO_PREFIX = ""; 342 | }; 343 | name = Release; 344 | }; 345 | 340EEEBE1DB2F4A3003BE19E /* Debug */ = { 346 | isa = XCBuildConfiguration; 347 | buildSettings = { 348 | CLANG_ENABLE_MODULES = YES; 349 | CODE_SIGN_IDENTITY = ""; 350 | DEFINES_MODULE = YES; 351 | DYLIB_COMPATIBILITY_VERSION = 1; 352 | DYLIB_CURRENT_VERSION = 1; 353 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 354 | INFOPLIST_FILE = NonEmptyArray/Info.plist; 355 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 356 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 357 | PRODUCT_BUNDLE_IDENTIFIER = com.khanlou.NonEmptyArray; 358 | PRODUCT_NAME = "$(TARGET_NAME)"; 359 | SKIP_INSTALL = YES; 360 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 361 | SWIFT_VERSION = 3.0; 362 | }; 363 | name = Debug; 364 | }; 365 | 340EEEBF1DB2F4A3003BE19E /* Release */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | CLANG_ENABLE_MODULES = YES; 369 | CODE_SIGN_IDENTITY = ""; 370 | DEFINES_MODULE = YES; 371 | DYLIB_COMPATIBILITY_VERSION = 1; 372 | DYLIB_CURRENT_VERSION = 1; 373 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 374 | INFOPLIST_FILE = NonEmptyArray/Info.plist; 375 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 377 | PRODUCT_BUNDLE_IDENTIFIER = com.khanlou.NonEmptyArray; 378 | PRODUCT_NAME = "$(TARGET_NAME)"; 379 | SKIP_INSTALL = YES; 380 | SWIFT_VERSION = 3.0; 381 | }; 382 | name = Release; 383 | }; 384 | 340EEEC11DB2F4A3003BE19E /* Debug */ = { 385 | isa = XCBuildConfiguration; 386 | buildSettings = { 387 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 388 | INFOPLIST_FILE = NonEmptyArrayTests/Info.plist; 389 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 390 | PRODUCT_BUNDLE_IDENTIFIER = com.khanlou.NonEmptyArrayTests; 391 | PRODUCT_NAME = "$(TARGET_NAME)"; 392 | SWIFT_VERSION = 3.0; 393 | }; 394 | name = Debug; 395 | }; 396 | 340EEEC21DB2F4A3003BE19E /* Release */ = { 397 | isa = XCBuildConfiguration; 398 | buildSettings = { 399 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 400 | INFOPLIST_FILE = NonEmptyArrayTests/Info.plist; 401 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 402 | PRODUCT_BUNDLE_IDENTIFIER = com.khanlou.NonEmptyArrayTests; 403 | PRODUCT_NAME = "$(TARGET_NAME)"; 404 | SWIFT_VERSION = 3.0; 405 | }; 406 | name = Release; 407 | }; 408 | /* End XCBuildConfiguration section */ 409 | 410 | /* Begin XCConfigurationList section */ 411 | 340EEEA31DB2F4A2003BE19E /* Build configuration list for PBXProject "NonEmptyArray" */ = { 412 | isa = XCConfigurationList; 413 | buildConfigurations = ( 414 | 340EEEBB1DB2F4A3003BE19E /* Debug */, 415 | 340EEEBC1DB2F4A3003BE19E /* Release */, 416 | ); 417 | defaultConfigurationIsVisible = 0; 418 | defaultConfigurationName = Release; 419 | }; 420 | 340EEEBD1DB2F4A3003BE19E /* Build configuration list for PBXNativeTarget "NonEmptyArray" */ = { 421 | isa = XCConfigurationList; 422 | buildConfigurations = ( 423 | 340EEEBE1DB2F4A3003BE19E /* Debug */, 424 | 340EEEBF1DB2F4A3003BE19E /* Release */, 425 | ); 426 | defaultConfigurationIsVisible = 0; 427 | defaultConfigurationName = Release; 428 | }; 429 | 340EEEC01DB2F4A3003BE19E /* Build configuration list for PBXNativeTarget "NonEmptyArrayTests" */ = { 430 | isa = XCConfigurationList; 431 | buildConfigurations = ( 432 | 340EEEC11DB2F4A3003BE19E /* Debug */, 433 | 340EEEC21DB2F4A3003BE19E /* Release */, 434 | ); 435 | defaultConfigurationIsVisible = 0; 436 | defaultConfigurationName = Release; 437 | }; 438 | /* End XCConfigurationList section */ 439 | }; 440 | rootObject = 340EEEA01DB2F4A2003BE19E /* Project object */; 441 | } 442 | -------------------------------------------------------------------------------- /NonEmptyArray.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NonEmptyArray/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /NonEmptyArray/NonEmptyArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // NonEmptyArray.h 3 | // NonEmptyArray 4 | // 5 | // Created by Soroush Khanlou on 10/15/16. 6 | // Copyright © 2016 Soroush Khanlou. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for NonEmptyArray. 12 | FOUNDATION_EXPORT double NonEmptyArrayVersionNumber; 13 | 14 | //! Project version string for NonEmptyArray. 15 | FOUNDATION_EXPORT const unsigned char NonEmptyArrayVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /NonEmptyArray/NonEmptyArray.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NonEmptyArray.swift 3 | // NonEmptyArray 4 | // 5 | // Created by Soroush Khanlou on 10/15/16. 6 | // Copyright © 2016 Soroush Khanlou. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public struct InvalidArrayError: Error { } 12 | 13 | public struct NonEmptyArray { 14 | 15 | fileprivate var elements: Array 16 | 17 | public init?(array: [Element]) { 18 | guard !array.isEmpty else { 19 | return nil 20 | } 21 | self.elements = array 22 | } 23 | 24 | public init(elements: Element...) { 25 | self.elements = elements 26 | } 27 | 28 | public init?(_ sequence: S) where S.Iterator.Element == Element { 29 | self.init(array: Array(sequence)) 30 | } 31 | 32 | public init?() { 33 | return nil 34 | } 35 | 36 | public var count: Int { 37 | return elements.count 38 | } 39 | 40 | public var first: Element { 41 | return elements.first! 42 | } 43 | 44 | public var last: Element { 45 | return elements.last! 46 | } 47 | 48 | public var isEmpty: Bool { 49 | return false 50 | } 51 | 52 | public func min(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> Element { 53 | return try elements.min(by: areInIncreasingOrder)! 54 | } 55 | 56 | public func max(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> Element { 57 | return try elements.max(by: areInIncreasingOrder)! 58 | } 59 | 60 | public mutating func insert(contentsOf collection: C, at index: Index) where C.Iterator.Element == Element { 61 | elements.insert(contentsOf: collection, at: index) 62 | } 63 | 64 | public mutating func insert(_ newElement: Element, at index: Index) { 65 | elements.insert(newElement, at: index) 66 | } 67 | 68 | public mutating func append(_ newElement: Element) { 69 | elements.append(newElement) 70 | } 71 | 72 | public func appending(_ newElement: Element) -> NonEmptyArray { 73 | var copy = self 74 | copy.append(newElement) 75 | return copy 76 | } 77 | 78 | public mutating func remove(at index: Index) throws { 79 | if elements.count == 1 { 80 | throw InvalidArrayError() 81 | } 82 | elements.remove(at: index) 83 | } 84 | 85 | public mutating func removeFirst() throws { 86 | if elements.count == 1 { 87 | throw InvalidArrayError() 88 | } 89 | elements.removeFirst() 90 | } 91 | 92 | public mutating func removeFirst(_ n: Int) throws { 93 | if elements.count <= n { 94 | throw InvalidArrayError() 95 | } 96 | elements.removeFirst(n) 97 | } 98 | 99 | public mutating func removeLast() throws { 100 | if elements.count == 1 { 101 | throw InvalidArrayError() 102 | } 103 | elements.removeLast() 104 | } 105 | 106 | public mutating func removeLast(_ n: Int) throws { 107 | if elements.count <= n { 108 | throw InvalidArrayError() 109 | } 110 | elements.removeLast(n) 111 | } 112 | 113 | public mutating func popLast() throws -> Element { 114 | if elements.count == 1 { 115 | throw InvalidArrayError() 116 | } 117 | return elements.popLast()! 118 | } 119 | } 120 | 121 | extension NonEmptyArray: CustomStringConvertible { 122 | public var description: String { 123 | return elements.description 124 | } 125 | } 126 | 127 | extension NonEmptyArray: CustomDebugStringConvertible { 128 | public var debugDescription: String { 129 | return elements.debugDescription 130 | } 131 | } 132 | 133 | extension NonEmptyArray: Collection { 134 | public typealias Index = Int 135 | 136 | public var startIndex: Int { 137 | return 0 138 | } 139 | 140 | public var endIndex: Int { 141 | return count 142 | } 143 | 144 | public func index(after i: Int) -> Int { 145 | return i + 1 146 | } 147 | } 148 | 149 | extension NonEmptyArray: MutableCollection { 150 | public subscript(_ index: Int) -> Element { 151 | get { 152 | return elements[index] 153 | } 154 | set { 155 | elements[index] = newValue 156 | } 157 | } 158 | } 159 | 160 | extension NonEmptyArray where Element: Comparable { 161 | public func min() -> Element { 162 | return elements.min()! 163 | } 164 | 165 | public func max() -> Element { 166 | return elements.max()! 167 | } 168 | 169 | public mutating func sort() { 170 | elements.sort() 171 | } 172 | } 173 | 174 | public func ==(lhs: NonEmptyArray, rhs: NonEmptyArray) -> Bool { 175 | return lhs.elements == rhs.elements 176 | } 177 | 178 | public func !=(lhs: NonEmptyArray, rhs: NonEmptyArray) -> Bool { 179 | return lhs.elements != rhs.elements 180 | } 181 | -------------------------------------------------------------------------------- /NonEmptyArrayTests/AppendingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppendingTests.swift 3 | // NonEmptyArray 4 | // 5 | // Created by Soroush Khanlou on 10/16/16. 6 | // Copyright © 2016 Soroush Khanlou. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | import NonEmptyArray 12 | 13 | class AppendingTests: XCTestCase { 14 | 15 | let array = NonEmptyArray(elements: 1, 2, 3) 16 | 17 | func testAppend() { 18 | var copy = array 19 | copy.append(2) 20 | XCTAssertEqual(copy.count, 4) 21 | XCTAssertEqual(copy.last, 2) 22 | } 23 | 24 | func testAppending() { 25 | let appended = array.appending(7) 26 | XCTAssertEqual(appended.count, 4) 27 | XCTAssertEqual(appended.last, 7) 28 | } 29 | 30 | func testInsertion() { 31 | var copy = array 32 | copy.insert(2, at: 1) 33 | XCTAssertEqual(Array(copy), [1, 2, 2, 3]) 34 | } 35 | 36 | func testCollectionInsertion() { 37 | var copy = array 38 | copy.insert(contentsOf: AnyCollection([1, 2, 3]), at: 2) 39 | XCTAssertEqual(Array(copy), [1, 2, 1, 2, 3, 3]) 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /NonEmptyArrayTests/ComparableTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ComparableTests.swift 3 | // NonEmptyArray 4 | // 5 | // Created by Soroush Khanlou on 10/16/16. 6 | // Copyright © 2016 Soroush Khanlou. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | import NonEmptyArray 12 | 13 | class ComparableTests: XCTestCase { 14 | 15 | let array = NonEmptyArray(elements: 2, 1, 3) 16 | 17 | func testMinAndMax() { 18 | XCTAssertEqual(array.min(), 1) 19 | XCTAssertEqual(array.max(), 3) 20 | } 21 | 22 | func testSort() { 23 | var copy = array 24 | copy.sort() 25 | XCTAssertTrue(copy == NonEmptyArray(elements: 1, 2, 3)) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /NonEmptyArrayTests/EqualityTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EqualityTests.swift 3 | // NonEmptyArray 4 | // 5 | // Created by Soroush Khanlou on 10/16/16. 6 | // Copyright © 2016 Soroush Khanlou. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | import NonEmptyArray 12 | 13 | class EqualityTests: XCTestCase { 14 | 15 | let first = NonEmptyArray(elements: 1, 2, 3) 16 | let second = NonEmptyArray(elements: 1, 2, 3) 17 | let third = NonEmptyArray(elements: 1, 2) 18 | 19 | func testEquality() { 20 | XCTAssertTrue(first == second) 21 | XCTAssertFalse(first == third) 22 | } 23 | 24 | func testNonEqualArrays() { 25 | XCTAssertFalse(first != second) 26 | XCTAssertTrue(first != third) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /NonEmptyArrayTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /NonEmptyArrayTests/NonComparableTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NonComparableTests.swift 3 | // NonEmptyArray 4 | // 5 | // Created by Soroush Khanlou on 10/16/16. 6 | // Copyright © 2016 Soroush Khanlou. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | import NonEmptyArray 12 | 13 | class NonComparableTests: XCTestCase { 14 | 15 | struct Wrapper { 16 | let value: Int 17 | } 18 | 19 | let array = NonEmptyArray(elements: Wrapper(value: 1), Wrapper(value: 2), Wrapper(value: 3)) 20 | 21 | func testNonOptionalMethods() { 22 | XCTAssert(type(of: array.min(by: { $0.value < $1.value })) == Wrapper.self) 23 | XCTAssert(type(of: array.min(by: { $0.value < $1.value })) != Optional.self) 24 | 25 | XCTAssert(type(of: array.max(by: { $0.value < $1.value })) == Wrapper.self) 26 | XCTAssert(type(of: array.max(by: { $0.value < $1.value })) != Optional.self) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /NonEmptyArrayTests/NonEmptyArrayTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NonEmptyArrayTests.swift 3 | // NonEmptyArrayTests 4 | // 5 | // Created by Soroush Khanlou on 10/15/16. 6 | // Copyright © 2016 Soroush Khanlou. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | import NonEmptyArray 12 | 13 | class NonEmptyArrayTests: XCTestCase { 14 | 15 | let nilArray = NonEmptyArray(array: []) 16 | 17 | let notNilArray = NonEmptyArray(array: [1, 2, 3]) 18 | 19 | let array = NonEmptyArray(elements: 1, 2, 3) 20 | 21 | func testEmptyArrayInitializers() { 22 | XCTAssertNil(nilArray) 23 | XCTAssertNotNil(notNilArray) 24 | 25 | XCTAssertNil(NonEmptyArray()) 26 | } 27 | 28 | func testSequenceInitializer() { 29 | let sequenceInitalized = NonEmptyArray(AnySequence([1, 2, 3])) 30 | if let nonEmptyArray = sequenceInitalized { 31 | XCTAssertTrue(array == nonEmptyArray) 32 | } else { 33 | XCTFail() 34 | } 35 | 36 | XCTAssertNil(NonEmptyArray(AnySequence([]))) 37 | } 38 | 39 | func testArray() { 40 | XCTAssertEqual(array.count, 3) 41 | } 42 | 43 | func testNonOptionalMethods() { 44 | XCTAssert(type(of: array.min()) == Int.self) 45 | XCTAssert(type(of: array.min()) != Optional.self) 46 | 47 | XCTAssert(type(of: array.max()) == Int.self) 48 | XCTAssert(type(of: array.max()) != Optional.self) 49 | 50 | XCTAssert(type(of: array.first) == Int.self) 51 | XCTAssert(type(of: array.first) != Optional.self) 52 | 53 | XCTAssert(type(of: array.last) == Int.self) 54 | XCTAssert(type(of: array.last) != Optional.self) 55 | } 56 | 57 | func testDescriptions() { 58 | XCTAssertEqual(array.description, "[1, 2, 3]") 59 | XCTAssertEqual(array.debugDescription, "[1, 2, 3]") 60 | } 61 | 62 | func testSubscripting() { 63 | XCTAssertEqual(array[0], 1) 64 | XCTAssertEqual(array[1], 2) 65 | XCTAssertEqual(array[2], 3) 66 | XCTAssertEqual(array[1..<2].first, 2) 67 | } 68 | 69 | func testSubscriptMutation() { 70 | var copy = array 71 | copy[0] = 0 72 | XCTAssertEqual(copy[0], 0, "A mutable Array should support subscript set operation.") 73 | } 74 | 75 | func testSequence() { 76 | let anySequence = AnySequence(array) 77 | let count = anySequence.reduce(0, { $0.0 + 1 }) 78 | XCTAssertEqual(count, array.count) 79 | } 80 | 81 | func testCollection() { 82 | let anyCollection = AnyCollection(array) 83 | let count = anyCollection.reduce(0, { $0.0 + 1 }) 84 | XCTAssertEqual(count, array.count) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /NonEmptyArrayTests/RemovalTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RemovalTests.swift 3 | // NonEmptyArray 4 | // 5 | // Created by Soroush Khanlou on 10/16/16. 6 | // Copyright © 2016 Soroush Khanlou. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | import NonEmptyArray 12 | 13 | class RemovalTests: XCTestCase { 14 | 15 | let array = NonEmptyArray(elements: 1, 2, 3) 16 | 17 | func testRemoveAt() { 18 | var copy = array 19 | try? copy.remove(at: 1) 20 | XCTAssertEqual(Array(copy), [1, 3]) 21 | try? copy.remove(at: 0) 22 | XCTAssertEqual(Array(copy), [3]) 23 | try? copy.remove(at: 0) 24 | XCTAssertEqual(Array(copy), [3]) 25 | do { 26 | try copy.remove(at: 0) 27 | XCTFail() 28 | } catch let error { 29 | XCTAssert(error is InvalidArrayError) 30 | } 31 | } 32 | 33 | func testRemoveFirst() { 34 | var copy = array 35 | try? copy.removeFirst() 36 | XCTAssertEqual(Array(copy), [2, 3]) 37 | try? copy.removeFirst() 38 | XCTAssertEqual(Array(copy), [3]) 39 | try? copy.removeFirst() 40 | XCTAssertEqual(Array(copy), [3]) 41 | do { 42 | try copy.removeFirst() 43 | XCTFail() 44 | } catch let error { 45 | XCTAssert(error is InvalidArrayError) 46 | } 47 | } 48 | 49 | func testRemoveLast() { 50 | var copy = array 51 | try? copy.removeLast() 52 | XCTAssertEqual(Array(copy), [1, 2]) 53 | try? copy.removeLast() 54 | XCTAssertEqual(Array(copy), [1]) 55 | try? copy.removeLast() 56 | XCTAssertEqual(Array(copy), [1]) 57 | do { 58 | try copy.removeLast() 59 | XCTFail() 60 | } catch let error { 61 | XCTAssert(error is InvalidArrayError) 62 | } 63 | } 64 | 65 | func testRemoveFirstN() { 66 | var copy = array 67 | try? copy.removeFirst(2) 68 | XCTAssertEqual(Array(copy), [3]) 69 | try? copy.removeFirst(2) 70 | XCTAssertEqual(Array(copy), [3]) 71 | copy.append(8) 72 | try? copy.removeFirst(2) 73 | XCTAssertEqual(Array(copy), [3, 8]) 74 | do { 75 | try copy.removeFirst(2) 76 | XCTFail() 77 | } catch let error { 78 | XCTAssert(error is InvalidArrayError) 79 | } 80 | } 81 | 82 | func testRemoveLastN() { 83 | var copy = array 84 | try? copy.removeLast(2) 85 | XCTAssertEqual(Array(copy), [1]) 86 | try? copy.removeLast(2) 87 | XCTAssertEqual(Array(copy), [1]) 88 | copy.append(6) 89 | try? copy.removeLast(2) 90 | XCTAssertEqual(Array(copy), [1, 6]) 91 | do { 92 | try copy.removeLast(2) 93 | XCTFail() 94 | } catch let error { 95 | XCTAssert(error is InvalidArrayError) 96 | } 97 | } 98 | 99 | func testPopLast() { 100 | var copy = array 101 | var last = try? copy.popLast() 102 | XCTAssertEqual(Array(copy), [1, 2]) 103 | XCTAssertEqual(last, 3) 104 | last = try? copy.popLast() 105 | XCTAssertEqual(Array(copy), [1]) 106 | XCTAssertEqual(last, 2) 107 | last = try? copy.popLast() 108 | XCTAssertEqual(Array(copy), [1]) 109 | XCTAssertNil(last) 110 | do { 111 | let _ = try copy.popLast() 112 | XCTFail() 113 | } catch let error { 114 | XCTAssert(error is InvalidArrayError) 115 | } 116 | 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NonEmptyArray 2 | An array in Swift that can't be empty 3 | --------------------------------------------------------------------------------