Skip to content

Commit

Permalink
Merge branch 'master' of github.com:boinx/BXSwiftUtils
Browse files Browse the repository at this point in the history
  • Loading branch information
peterb180369 committed Nov 22, 2018
2 parents 748b6ea + 6b1934f commit bf561c5
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ matrix:
- osx_image: xcode10
env: SCHEME="BXSwiftUtils" DESTINATION="platform=macOS,arch=x86_64"
- osx_image: xcode10
env: SCHEME="BXSwiftUtilsx" DESTINATION="platform=iOS Simulator,name=iPhone X,OS=12.0"
env: SCHEME="BXSwiftUtils" DESTINATION="platform=iOS Simulator,name=iPhone X,OS=12.0"
- osx_image: xcode10
env: CREATE_RELEASE="true"
script: sh deploy.sh
Expand Down
22 changes: 18 additions & 4 deletions BXSwiftUtils.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
48C248142088CF4100DC9317 /* NSAttributedString+CodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C248132088CF4100DC9317 /* NSAttributedString+CodableTests.swift */; };
48C3DF6620E10DC300359288 /* TypedKVO+propagateChanges.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C3DF6420E10DC300359288 /* TypedKVO+propagateChanges.swift */; };
48C3DF6820E10E2400359288 /* TypedKVO+propagateChangesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C3DF6720E10E2400359288 /* TypedKVO+propagateChangesTests.swift */; };
48D9E36121A6B75E0057B930 /* Comparable+ClipTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D9E36021A6B75E0057B930 /* Comparable+ClipTests.swift */; };
48DA8193206A4E9C009D1E6C /* KVOTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48DA8192206A4E9C009D1E6C /* KVOTests.swift */; };
48DA8199206A50DB009D1E6C /* NSException+ToSwiftError.h in Headers */ = {isa = PBXBuildFile; fileRef = 48DA8196206A50DB009D1E6C /* NSException+ToSwiftError.h */; settings = {ATTRIBUTES = (Public, ); }; };
48DA819B206A50DB009D1E6C /* NSException+ToSwiftError.m in Sources */ = {isa = PBXBuildFile; fileRef = 48DA8197206A50DB009D1E6C /* NSException+ToSwiftError.m */; };
Expand Down Expand Up @@ -142,6 +143,7 @@
48C248132088CF4100DC9317 /* NSAttributedString+CodableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+CodableTests.swift"; sourceTree = "<group>"; };
48C3DF6420E10DC300359288 /* TypedKVO+propagateChanges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TypedKVO+propagateChanges.swift"; sourceTree = "<group>"; };
48C3DF6720E10E2400359288 /* TypedKVO+propagateChangesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TypedKVO+propagateChangesTests.swift"; sourceTree = "<group>"; };
48D9E36021A6B75E0057B930 /* Comparable+ClipTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Comparable+ClipTests.swift"; sourceTree = "<group>"; };
48DA8192206A4E9C009D1E6C /* KVOTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KVOTests.swift; sourceTree = "<group>"; };
48DA8196206A50DB009D1E6C /* NSException+ToSwiftError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSException+ToSwiftError.h"; sourceTree = "<group>"; };
48DA8197206A50DB009D1E6C /* NSException+ToSwiftError.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSException+ToSwiftError.m"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -290,6 +292,7 @@
D06CC9212178C096009C2991 /* Files */,
48C248122088CF1C00DC9317 /* Strings */,
D06CC9292178D22A009C2991 /* Data */,
48D9E35F21A6B73D0057B930 /* Math & Geometry */,
4875F24C2051EC75009985EC /* Collection */,
489E56A72052CAB30071BBF1 /* Logging */,
4853E3882056BDB500938B82 /* Threading */,
Expand Down Expand Up @@ -397,6 +400,14 @@
path = Strings;
sourceTree = "<group>";
};
48D9E35F21A6B73D0057B930 /* Math & Geometry */ = {
isa = PBXGroup;
children = (
48D9E36021A6B75E0057B930 /* Comparable+ClipTests.swift */,
);
path = "Math & Geometry";
sourceTree = "<group>";
};
48DA8195206A509A009D1E6C /* Exceptions */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -695,6 +706,7 @@
D06CC91F2178B089009C2991 /* String+RegexTests.swift in Sources */,
D06CC9272178D209009C2991 /* Data+MutationTests.swift in Sources */,
48DE068D20876E52000246CD /* Dictionary+EnumKeysTests.swift in Sources */,
48D9E36121A6B75E0057B930 /* Comparable+ClipTests.swift in Sources */,
4853E38A2056BDE400938B82 /* SynchronizedTests.swift in Sources */,
4826E581208F534000A5BA9B /* Array+DecodableTests.swift in Sources */,
48FF9BCA20E1174C00024C10 /* Weak.swift in Sources */,
Expand Down Expand Up @@ -906,7 +918,8 @@
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = BXSwiftUtilsTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.boinx.$(TARGET_NAME)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
Expand All @@ -921,7 +934,8 @@
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = BXSwiftUtilsTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.boinx.$(TARGET_NAME)";
PRODUCT_NAME = "$(TARGET_NAME)";
};
Expand All @@ -930,6 +944,7 @@
4875F271205299A6009985EC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ENABLE_MODULES = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
Expand All @@ -939,7 +954,6 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.14;
PRODUCT_BUNDLE_IDENTIFIER = com.boinx.BXSwiftUtils;
PRODUCT_NAME = BXSwiftUtils;
SKIP_INSTALL = YES;
Expand All @@ -960,6 +974,7 @@
4875F272205299A6009985EC /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ENABLE_MODULES = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
Expand All @@ -969,7 +984,6 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.14;
PRODUCT_BUNDLE_IDENTIFIER = com.boinx.BXSwiftUtils;
PRODUCT_NAME = BXSwiftUtils;
SKIP_INSTALL = YES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,26 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4875F20F2051E70E009985EC"
BuildableName = "BXSwiftUtils-Tests.xctest"
BlueprintName = "BXSwiftUtils-Tests"
ReferencedContainer = "container:BXSwiftUtils.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4875F25E205299A6009985EC"
BuildableName = "BXSwiftUtils.framework"
BlueprintName = "BXSwiftUtils"
ReferencedContainer = "container:BXSwiftUtils.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
Expand Down
69 changes: 54 additions & 15 deletions BXSwiftUtils/Math & Geometry/Comparable+Clip.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,63 @@ import Foundation

extension Comparable
{
/// Returns `self` clipped to the closed interval `[minValue, maxValue]`.
///
/// - Parameters:
/// - minValue: The minimum allowed value. Will clip `self` if smaller.
/// - maxValue: The maximum allowed value. Will clip `self` if greater.
/// - Returns: `self` if `self` is within the interval `[minValue, maxValue]`, `minValue` or `maxValue` otherwise.
public func clipped<T>(minValue: T, maxValue: T) -> T where T : Comparable
/**
Clips a value into the closed range `[min, max]` without modifying the original value.

- Parameter minValue: The minimum allowed value.
- Parameter maxValue: The maximum allowed value.
- Returns: A new value that lies within the closed range `[min, max]`.
*/
public func clipped(min minValue: Self, max maxValue: Self) -> Self
{
var copy = self
copy.clip(min: minValue, max: maxValue)
return copy
}

/**
Clips a value into the closed range `[min, max]` by modifying the original value.

- Parameter minValue: The minimum allowed value.
- Parameter maxValue: The maximum allowed value.
*/
public mutating func clip(min minValue: Self, max maxValue: Self)
{
return min(maxValue, max(minValue, self as! T))
if minValue > maxValue
{
NSException.raise(.invalidArgumentException, format: "Can't clip value \(self) with maxValue \(maxValue) being larger than minValue \(minValue)", arguments: getVaList([]))
}

if self < minValue
{
self = minValue
}
else if self > maxValue
{
self = maxValue
}
}

/// Clips to the closed interval `[minValue, maxValue]`.
///
/// - Parameters:
/// - minValue: The minimum allowed value. Will clip `self` if smaller.
/// - maxValue: The maximum allowed value. Will clip `self` if greater.
public mutating func clip<T>(minValue: T, maxValue: T) where T : Comparable
/**
Clips a value into the given closed range without modifying the original value.

- Parameter range: Closed range that conveys the minimum and maximum allowed value.
- Returns: New value that lies within the closed range `range`.
*/
public func clipped(to range: ClosedRange<Self>) -> Self
{
var copy = self
copy.clip(min: range.lowerBound, max: range.upperBound)
return copy
}

/**
Clips a value into the given closed range by modifying the original value.

- Parameter range: Closed range that conveys the minimum and maximum allowed value.
*/
public mutating func clip(to range: ClosedRange<Self>)
{
self = min(maxValue, max(minValue, self as! T)) as! Self
self.clip(min: range.lowerBound, max: range.upperBound)
}
}
56 changes: 56 additions & 0 deletions BXSwiftUtilsTests/Math & Geometry/Comparable+ClipTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// Comparable+ClipTests.swift
// BXSwiftUtils-Tests
//
// Created by Stefan Fochler on 22.11.18.
// Copyright © 2018 Boinx Software Ltd. & Imagine GbR. All rights reserved.
//

import XCTest
import BXSwiftUtils

class Comparable_ClipTests : XCTestCase
{
func testClippedMinMax()
{
XCTAssertEqual(5.0.clipped(min: 0.0, max: 10.0), 5.0)
XCTAssertEqual(5.0.clipped(min: 0.0, max: 5.0), 5.0)
XCTAssertEqual(5.0.clipped(min: 0.0, max: 4.0), 4.0)
XCTAssertEqual(5.0.clipped(min: 6.0, max: 10.0), 6.0)
}

func testClippedRange()
{
XCTAssertEqual(5.0.clipped(to: 0...10), 5.0)
XCTAssertEqual(5.0.clipped(to: 0...5), 5.0)
XCTAssertEqual(5.0.clipped(to: 0...4), 4.0)
XCTAssertEqual(5.0.clipped(to: 6...10), 6.0)
}

func testClipMinMax()
{
var value = 5.0
value.clip(min: 2.0, max: 3.0)
XCTAssertEqual(value, 3.0)
}

func testClipRange()
{
var value = 5.0
value.clip(to: 2...3)
XCTAssertEqual(value, 3.0)
}

func testInvalidMinMax()
{
XCTAssertThrowsError(try NSException.toSwiftError
{
let _ = 5.0.clipped(min: 10.0, max: 0)
})
XCTAssertThrowsError(try NSException.toSwiftError
{
var value = 5.0
value.clip(min: 10.0, max: 0)
})
}
}
4 changes: 2 additions & 2 deletions deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ _artifacts="Artifacts"
rm -Rf "$_artifacts"
mkdir "$_artifacts"

set -o pipefail; xcodebuild -scheme "BXSwiftUtils-macOS" -configuration "Release" clean build | xcpretty
set -o pipefail; xcodebuild -scheme "BXSwiftUtils" -configuration "Release" clean build | xcpretty

source .bx_build_env

pushd "$BUILD_PRODUCTS_DIR"
zip -ryq "$SRCROOT/$_artifacts/BXSwiftUtils-macOS.framework.zip" "$PRODUCT_NAME"
popd

set -o pipefail; xcodebuild -scheme "BXSwiftUtils-iOS" -configuration "Release" -destination "platform=iOS Simulator,name=iPhone X,OS=latest" clean build | xcpretty
set -o pipefail; xcodebuild -scheme "BXSwiftUtils" -configuration "Release" -destination "platform=iOS Simulator,name=iPhone X,OS=latest" clean build | xcpretty

source .bx_build_env

Expand Down

0 comments on commit bf561c5

Please sign in to comment.