From 3bb3e02491c999dff9a3b82f8b51108766f3765c Mon Sep 17 00:00:00 2001 From: Adam Bell Date: Mon, 4 Sep 2023 09:29:57 -0700 Subject: [PATCH] Bridge approximatelyEqual to Swift Numerics' Implementation --- .../Motion/Animations/BasicAnimation.swift | 8 +- .../Animations/Functions/DecayFunction.swift | 2 +- .../Functions/EasingFunctions.swift | 2 +- .../Animations/Functions/SpringFunction.swift | 4 +- .../Motion/Animations/SpringAnimation.swift | 12 +-- .../Motion/Protocols/EquatableEnough.swift | 13 +-- Tests/MotionTests/BasicAnimationTests.swift | 8 +- Tests/MotionTests/DecayAnimationTests.swift | 26 +++--- Tests/MotionTests/MotionTests.swift | 88 +++++++++---------- Tests/MotionTests/SpringAnimationTests.swift | 6 +- 10 files changed, 86 insertions(+), 83 deletions(-) diff --git a/Sources/Motion/Animations/BasicAnimation.swift b/Sources/Motion/Animations/BasicAnimation.swift index 2a6089be..ed98bbd3 100644 --- a/Sources/Motion/Animations/BasicAnimation.swift +++ b/Sources/Motion/Animations/BasicAnimation.swift @@ -126,7 +126,7 @@ public final class BasicAnimation: ValueAnimation: ValueAnimation(value: inout SIMDType, epsilon: inout SIMDType.EpsilonType, toValue: inout SIMDType) -> Bool { /* Must Be Mirrored Below */ - return value.approximatelyEqual(to: toValue, epsilon: epsilon) + return value.isApproximatelyEqual(to: toValue, epsilon: epsilon) } #else @_specialize(kind: partial, where SIMDType == SIMD2) @@ -190,7 +190,7 @@ public final class BasicAnimation: ValueAnimation(value: inout SIMDType, epsilon: inout SIMDType.EpsilonType, toValue: inout SIMDType) -> Bool { /* Must Be Mirrored Above */ - return value.approximatelyEqual(to: toValue, epsilon: epsilon) + return value.isApproximatelyEqual(to: toValue, epsilon: epsilon) } #endif @@ -209,7 +209,7 @@ public final class BasicAnimation: ValueAnimation { @_specialize(kind: partial, where SIMDType == SIMD64) @_specialize(kind: partial, where SIMDType == SIMD64) @inlinable public func roundSIMD(_ value: SIMDType, toNearest roundingFactor: SIMDType.Scalar) -> SIMDType { - if roundingFactor.approximatelyEqual(to: 0.0) { + if roundingFactor.isApproximatelyEqual(to: 0.0) { return value } diff --git a/Sources/Motion/Animations/Functions/EasingFunctions.swift b/Sources/Motion/Animations/Functions/EasingFunctions.swift index 0b59d4a6..e5c5d3b7 100644 --- a/Sources/Motion/Animations/Functions/EasingFunctions.swift +++ b/Sources/Motion/Animations/Functions/EasingFunctions.swift @@ -80,7 +80,7 @@ public struct EasingFunction: Hashable { @inlinable internal func solveAccumulatedTimeSIMD(_ range: ClosedRange, value: Value.SIMDType) -> CFTimeInterval? { guard let usableIndex = value.indices.first(where: { i -> Bool in let fractionComplete = value[i] / (range.upperBound[i] - range.lowerBound[i]) - return !(fractionComplete.approximatelyEqual(to: 0.0) || fractionComplete.approximatelyEqual(to: 1.0)) + return !(fractionComplete.isApproximatelyEqual(to: 0.0) || fractionComplete.isApproximatelyEqual(to: 1.0)) }) else { return nil } let fractionComplete = value[usableIndex] / (range.upperBound[usableIndex] - range.lowerBound[usableIndex]) diff --git a/Sources/Motion/Animations/Functions/SpringFunction.swift b/Sources/Motion/Animations/Functions/SpringFunction.swift index daf0fa6d..ecee9446 100644 --- a/Sources/Motion/Animations/Functions/SpringFunction.swift +++ b/Sources/Motion/Animations/Functions/SpringFunction.swift @@ -111,7 +111,7 @@ public struct SpringFunction { */ public mutating func configure(response response_: Value.SIMDType.Scalar, dampingRatio: Value.SIMDType.Scalar) { let response: Value.SIMDType.Scalar - if response_.approximatelyEqual(to: 0.0) { + if response_.isApproximatelyEqual(to: 0.0) { // Having a zero response is unsupported, so we'll just supply an arbitrarily small value. response = 0.0001 } else { @@ -183,7 +183,7 @@ public struct SpringFunction { // Derivative of the above analytic equation to get the speed of a spring. (velocity) let d_x = velocity_x0_dampingRatio_w0 * cos_wD_dt - x0 * (wD * sin_wD_dt) velocity = -(dampingRatio_w0 * x - decayEnvelope * d_x) - } else if dampingRatio.approximatelyEqual(to: 1.0) { + } else if dampingRatio.isApproximatelyEqual(to: 1.0) { let decayEnvelope = SIMDType.Scalar.exp(-w0 * dt) let A = x0 diff --git a/Sources/Motion/Animations/SpringAnimation.swift b/Sources/Motion/Animations/SpringAnimation.swift index cd17a680..220e339d 100644 --- a/Sources/Motion/Animations/SpringAnimation.swift +++ b/Sources/Motion/Animations/SpringAnimation.swift @@ -221,7 +221,7 @@ public final class SpringAnimation: ValueAnimation(value: inout SIMDType, epsilon: inout SIMDType.EpsilonType, toValue: inout SIMDType, velocity: inout SIMDType, previousValueDelta: inout SIMDType?) -> (valueResolved: Bool, velocityResolved: Bool) { /* Must Be Mirrored Below */ - let valueResolved = value.approximatelyEqual(to: toValue, epsilon: epsilon) + let valueResolved = value.isApproximatelyEqual(to: toValue, epsilon: epsilon) if !valueResolved, !resolvesUponReachingToValue { return (false, false) } @@ -239,7 +239,7 @@ public final class SpringAnimation: ValueAnimation` animating with `toValue` of 0.0, starting at 1.0, will have a value of ~0.1 on one frame, the next frame it could be either 0.0 or -0.1, in which case either the values have been reached or exeeded (sign changed from + to -). */ allValuesReachedOrExceededToValues = allValuesReachedOrExceededToValues && - (previousValueDelta[index].sign != currentValueDelta[index].sign) || (value[index].approximatelyEqual(to: toValue[index], epsilon: 0.01)) + (previousValueDelta[index].sign != currentValueDelta[index].sign) || (value[index].isApproximatelyEqual(to: toValue[index], epsilon: 0.01)) index += 1 } @@ -250,7 +250,7 @@ public final class SpringAnimation: ValueAnimation: ValueAnimation(value: inout SIMDType, epsilon: inout SIMDType.EpsilonType, toValue: inout SIMDType, velocity: inout SIMDType, previousValueDelta: inout SIMDType?) -> (valueResolved: Bool, velocityResolved: Bool) { /* Must Be Mirrored Above */ - let valueResolved = value.approximatelyEqual(to: toValue, epsilon: epsilon) + let valueResolved = value.isApproximatelyEqual(to: toValue, epsilon: epsilon) if !valueResolved, !resolvesUponReachingToValue { return (false, false) } @@ -289,7 +289,7 @@ public final class SpringAnimation: ValueAnimation` animating with `toValue` of 0.0, starting at 1.0, will have a value of ~0.1 on one frame, the next frame it could be either 0.0 or -0.1, in which case either the values have been reached or exeeded (sign changed from + to -). */ allValuesReachedOrExceededToValues = allValuesReachedOrExceededToValues && - (previousValueDelta[index].sign != currentValueDelta[index].sign) || (value[index].approximatelyEqual(to: toValue[index], epsilon: 0.01)) + (previousValueDelta[index].sign != currentValueDelta[index].sign) || (value[index].isApproximatelyEqual(to: toValue[index], epsilon: 0.01)) index += 1 } @@ -300,7 +300,7 @@ public final class SpringAnimation: ValueAnimation Bool + func isApproximatelyEqual(to: Self, epsilon: EpsilonType) -> Bool } @@ -85,9 +86,11 @@ public extension EquatableEnough where Self: FloatingPoint & FloatingPointInitia /** Declares whether or not something else is equal to `self` within a given tolerance. (e.g. a floating point value that is equal to another floating point value within a given epsilon) + + Bridges to Swift Numerics' `isApproximatelyEqual` (https://github.com/schwa/ApproximateEquality/blob/main/Sources/ApproximateEquality/ApproximateEquality.swift). */ - @inlinable func approximatelyEqual(to other: Self, epsilon: Self = .epsilon) -> Bool { - return abs(self - other) < epsilon + @inlinable func isApproximatelyEqual(to other: Self, epsilon: Self = .epsilon) -> Bool { + return isApproximatelyEqual(to: other, absoluteTolerance: epsilon, relativeTolerance: .zero) } } @@ -118,9 +121,9 @@ public extension EquatableEnough where Self: FloatingPoint & FloatingPointInitia */ extension SupportedSIMD where Self: EquatableEnough & Comparable, Scalar: SupportedScalar { - @inlinable public func approximatelyEqual(to other: Self, epsilon: Scalar = .epsilon) -> Bool { + @inlinable public func isApproximatelyEqual(to other: Self, epsilon: Scalar = .epsilon) -> Bool { for i in 0.. = 0.0...10.0 let startValue = easeIn.solveInterpolatedValue(range, fraction: 0.0) - XCTAssert(startValue.approximatelyEqual(to: range.lowerBound)) + XCTAssert(startValue.isApproximatelyEqual(to: range.lowerBound)) let endValue = easeIn.solveInterpolatedValue(range, fraction: 1.0) - XCTAssert(endValue.approximatelyEqual(to: range.upperBound)) + XCTAssert(endValue.isApproximatelyEqual(to: range.upperBound)) } func testBasicAnimationStartStop() { @@ -96,7 +96,7 @@ final class BasicAnimationTests: XCTestCase { let timeAccumulatedDeterminedFromValue = basicAnimation.accumulatedTime - XCTAssertTrue(timeAccumulated.approximatelyEqual(to: timeAccumulatedDeterminedFromValue)) + XCTAssertTrue(timeAccumulated.isApproximatelyEqual(to: timeAccumulatedDeterminedFromValue)) let expectBasicAnimationCompletionCalled = XCTestExpectation(description: "Basic animation completed") basicAnimation.completion = { @@ -121,7 +121,7 @@ final class BasicAnimationTests: XCTestCase { XCTAssertEqual(keyframeAnimation.calculationMode, .discrete) XCTAssertFalse(keyframeAnimation.values?.isEmpty ?? true) XCTAssertFalse(keyframeAnimation.keyTimes?.isEmpty ?? true) - XCTAssertTrue(keyframeAnimation.duration.approximatelyEqual(to: 1.0)) + XCTAssertTrue(keyframeAnimation.duration.isApproximatelyEqual(to: 1.0)) } override class func tearDown() { diff --git a/Tests/MotionTests/DecayAnimationTests.swift b/Tests/MotionTests/DecayAnimationTests.swift index 76601938..c2dc72d6 100644 --- a/Tests/MotionTests/DecayAnimationTests.swift +++ b/Tests/MotionTests/DecayAnimationTests.swift @@ -82,28 +82,28 @@ final class DecayAnimationTests: XCTestCase { let decay = DecayAnimation() decay.velocity = 2000.0 - XCTAssertTrue(decay.toValue.approximatelyEqual(to: 998.999)) - XCTAssertTrue(decay._toValue.approximatelyEqual(to: SIMD2(998.999, 0.0))) + XCTAssertTrue(decay.toValue.isApproximatelyEqual(to: 998.999)) + XCTAssertTrue(decay._toValue.isApproximatelyEqual(to: SIMD2(998.999, 0.0))) let decay2 = DecayAnimation() decay2.velocity = CGPoint(x: 1000.0, y: 2000.0) - XCTAssertTrue(decay2.toValue.x.approximatelyEqual(to: 499.499) && decay2.toValue.y.approximatelyEqual(to: 998.999)) - XCTAssertTrue(decay2._toValue.approximatelyEqual(to: SIMD2(499.499, 998.999))) + XCTAssertTrue(decay2.toValue.x.isApproximatelyEqual(to: 499.499) && decay2.toValue.y.isApproximatelyEqual(to: 998.999)) + XCTAssertTrue(decay2._toValue.isApproximatelyEqual(to: SIMD2(499.499, 998.999))) } func testDecayVelocityCalculation() { let decay = DecayAnimation() decay.toValue = 998.999 - XCTAssertTrue(decay.velocity.approximatelyEqual(to: 2000.0, epsilon: 0.01)) - XCTAssertTrue(decay._velocity.approximatelyEqual(to: SIMD2(2000.0, 0.0), epsilon: 0.01)) + XCTAssertTrue(decay.velocity.isApproximatelyEqual(to: 2000.0, epsilon: 0.01)) + XCTAssertTrue(decay._velocity.isApproximatelyEqual(to: SIMD2(2000.0, 0.0), epsilon: 0.01)) let decay2 = DecayAnimation() decay2.toValue = CGPoint(x: 499.499, y: 998.999) - XCTAssertTrue(decay2.velocity.x.approximatelyEqual(to: 1000.0, epsilon: 0.01) && decay2.velocity.y.approximatelyEqual(to: 2000.0, epsilon: 0.01)) - XCTAssertTrue(decay2._velocity.approximatelyEqual(to: SIMD2(1000.0, 2000.0), epsilon: 0.01)) + XCTAssertTrue(decay2.velocity.x.isApproximatelyEqual(to: 1000.0, epsilon: 0.01) && decay2.velocity.y.isApproximatelyEqual(to: 2000.0, epsilon: 0.01)) + XCTAssertTrue(decay2._velocity.isApproximatelyEqual(to: SIMD2(1000.0, 2000.0), epsilon: 0.01)) } func testDecayRoundingFactorApplication() { @@ -111,15 +111,15 @@ final class DecayAnimationTests: XCTestCase { decay.roundingFactor = 1.0 decay.velocity = 200.0 - XCTAssertTrue(decay.velocity.approximatelyEqual(to: 200.2, epsilon: 0.001)) - XCTAssertTrue(decay.toValue.approximatelyEqual(to: 100.0, epsilon: 0.001)) + XCTAssertTrue(decay.velocity.isApproximatelyEqual(to: 200.2, epsilon: 0.001)) + XCTAssertTrue(decay.toValue.isApproximatelyEqual(to: 100.0, epsilon: 0.001)) let decay2 = DecayAnimation() decay2.roundingFactor = 1.0 / 3.0 // i.e. 3x device decay2.velocity = 200.90 - XCTAssertTrue(decay2.velocity.approximatelyEqual(to: 200.867, epsilon: 0.001)) - XCTAssertTrue(decay2.toValue.approximatelyEqual(to: 100.333, epsilon: 0.001)) + XCTAssertTrue(decay2.velocity.isApproximatelyEqual(to: 200.867, epsilon: 0.001)) + XCTAssertTrue(decay2.toValue.isApproximatelyEqual(to: 100.333, epsilon: 0.001)) } // MARK: - CAKeyframeAnimationEmittable Tests @@ -133,7 +133,7 @@ final class DecayAnimationTests: XCTestCase { XCTAssertEqual(keyframeAnimation.calculationMode, .discrete) XCTAssertFalse(keyframeAnimation.values?.isEmpty ?? true) XCTAssertFalse(keyframeAnimation.keyTimes?.isEmpty ?? true) - XCTAssertTrue(keyframeAnimation.duration.approximatelyEqual(to: 4.166)) + XCTAssertTrue(keyframeAnimation.duration.isApproximatelyEqual(to: 4.166)) } override class func tearDown() { diff --git a/Tests/MotionTests/MotionTests.swift b/Tests/MotionTests/MotionTests.swift index ac4fced1..69be6921 100644 --- a/Tests/MotionTests/MotionTests.swift +++ b/Tests/MotionTests/MotionTests.swift @@ -11,36 +11,36 @@ final class MotionTests: XCTestCase { let equalValue1 = 0.001 let equalValue2 = 0.001 - XCTAssert(equalValue1.approximatelyEqual(to: equalValue2) && (equalValue1 == equalValue2)) + XCTAssert(equalValue1.isApproximatelyEqual(to: equalValue2) && (equalValue1 == equalValue2)) // Mostly Equal let equalishValue3 = 0.0011 - XCTAssert(equalValue1.approximatelyEqual(to: equalishValue3)) + XCTAssert(equalValue1.isApproximatelyEqual(to: equalishValue3)) // Gotta love copy paste. // Would be neat to iterate over all the types, but I'm unsure how to do that. - XCTAssert(SIMD2(repeating: equalValue1).approximatelyEqual(to: SIMD2(repeating: equalishValue3))) - XCTAssert(SIMD3(repeating: equalValue1).approximatelyEqual(to: SIMD3(repeating: equalishValue3))) - XCTAssert(SIMD4(repeating: equalValue1).approximatelyEqual(to: SIMD4(repeating: equalishValue3))) - XCTAssert(SIMD8(repeating: equalValue1).approximatelyEqual(to: SIMD8(repeating: equalishValue3))) - XCTAssert(SIMD16(repeating: equalValue1).approximatelyEqual(to: SIMD16(repeating: equalishValue3))) - XCTAssert(SIMD32(repeating: equalValue1).approximatelyEqual(to: SIMD32(repeating: equalishValue3))) - XCTAssert(SIMD64(repeating: equalValue1).approximatelyEqual(to: SIMD64(repeating: equalishValue3))) + XCTAssert(SIMD2(repeating: equalValue1).isApproximatelyEqual(to: SIMD2(repeating: equalishValue3))) + XCTAssert(SIMD3(repeating: equalValue1).isApproximatelyEqual(to: SIMD3(repeating: equalishValue3))) + XCTAssert(SIMD4(repeating: equalValue1).isApproximatelyEqual(to: SIMD4(repeating: equalishValue3))) + XCTAssert(SIMD8(repeating: equalValue1).isApproximatelyEqual(to: SIMD8(repeating: equalishValue3))) + XCTAssert(SIMD16(repeating: equalValue1).isApproximatelyEqual(to: SIMD16(repeating: equalishValue3))) + XCTAssert(SIMD32(repeating: equalValue1).isApproximatelyEqual(to: SIMD32(repeating: equalishValue3))) + XCTAssert(SIMD64(repeating: equalValue1).isApproximatelyEqual(to: SIMD64(repeating: equalishValue3))) // Not Equal let nonEqualValue1 = 0.001 - let nonEqualValue2 = 0.002 + let nonEqualValue2 = 0.0021 - XCTAssertFalse(nonEqualValue1.approximatelyEqual(to: nonEqualValue2)) + XCTAssertFalse(nonEqualValue1.isApproximatelyEqual(to: nonEqualValue2)) - XCTAssertFalse(SIMD2(repeating: nonEqualValue1).approximatelyEqual(to: SIMD2(repeating: nonEqualValue2))) - XCTAssertFalse(SIMD3(repeating: nonEqualValue1).approximatelyEqual(to: SIMD3(repeating: nonEqualValue2))) - XCTAssertFalse(SIMD4(repeating: nonEqualValue1).approximatelyEqual(to: SIMD4(repeating: nonEqualValue2))) - XCTAssertFalse(SIMD8(repeating: nonEqualValue1).approximatelyEqual(to: SIMD8(repeating: nonEqualValue2))) - XCTAssertFalse(SIMD16(repeating: nonEqualValue1).approximatelyEqual(to: SIMD16(repeating: nonEqualValue2))) - XCTAssertFalse(SIMD32(repeating: nonEqualValue1).approximatelyEqual(to: SIMD32(repeating: nonEqualValue2))) - XCTAssertFalse(SIMD64(repeating: nonEqualValue1).approximatelyEqual(to: SIMD64(repeating: nonEqualValue2))) + XCTAssertFalse(SIMD2(repeating: nonEqualValue1).isApproximatelyEqual(to: SIMD2(repeating: nonEqualValue2))) + XCTAssertFalse(SIMD3(repeating: nonEqualValue1).isApproximatelyEqual(to: SIMD3(repeating: nonEqualValue2))) + XCTAssertFalse(SIMD4(repeating: nonEqualValue1).isApproximatelyEqual(to: SIMD4(repeating: nonEqualValue2))) + XCTAssertFalse(SIMD8(repeating: nonEqualValue1).isApproximatelyEqual(to: SIMD8(repeating: nonEqualValue2))) + XCTAssertFalse(SIMD16(repeating: nonEqualValue1).isApproximatelyEqual(to: SIMD16(repeating: nonEqualValue2))) + XCTAssertFalse(SIMD32(repeating: nonEqualValue1).isApproximatelyEqual(to: SIMD32(repeating: nonEqualValue2))) + XCTAssertFalse(SIMD64(repeating: nonEqualValue1).isApproximatelyEqual(to: SIMD64(repeating: nonEqualValue2))) // Less than XCTAssert(SIMD2(repeating: nonEqualValue1) < SIMD2(repeating: nonEqualValue2)) @@ -56,15 +56,15 @@ final class MotionTests: XCTestCase { let nonEqualValue4 = 0.002 let epsilon = 0.01 - XCTAssertTrue(nonEqualValue3.approximatelyEqual(to: nonEqualValue4, epsilon: epsilon)) + XCTAssertTrue(nonEqualValue3.isApproximatelyEqual(to: nonEqualValue4, epsilon: epsilon)) - XCTAssertTrue(SIMD2(repeating: nonEqualValue3).approximatelyEqual(to: SIMD2(repeating: nonEqualValue4), epsilon: epsilon)) - XCTAssertTrue(SIMD3(repeating: nonEqualValue3).approximatelyEqual(to: SIMD3(repeating: nonEqualValue4), epsilon: epsilon)) - XCTAssertTrue(SIMD4(repeating: nonEqualValue3).approximatelyEqual(to: SIMD4(repeating: nonEqualValue4), epsilon: epsilon)) - XCTAssertTrue(SIMD8(repeating: nonEqualValue3).approximatelyEqual(to: SIMD8(repeating: nonEqualValue4), epsilon: epsilon)) - XCTAssertTrue(SIMD16(repeating: nonEqualValue3).approximatelyEqual(to: SIMD16(repeating: nonEqualValue4), epsilon: epsilon)) - XCTAssertTrue(SIMD32(repeating: nonEqualValue3).approximatelyEqual(to: SIMD32(repeating: nonEqualValue4), epsilon: epsilon)) - XCTAssertTrue(SIMD64(repeating: nonEqualValue3).approximatelyEqual(to: SIMD64(repeating: nonEqualValue4), epsilon: epsilon)) + XCTAssertTrue(SIMD2(repeating: nonEqualValue3).isApproximatelyEqual(to: SIMD2(repeating: nonEqualValue4), epsilon: epsilon)) + XCTAssertTrue(SIMD3(repeating: nonEqualValue3).isApproximatelyEqual(to: SIMD3(repeating: nonEqualValue4), epsilon: epsilon)) + XCTAssertTrue(SIMD4(repeating: nonEqualValue3).isApproximatelyEqual(to: SIMD4(repeating: nonEqualValue4), epsilon: epsilon)) + XCTAssertTrue(SIMD8(repeating: nonEqualValue3).isApproximatelyEqual(to: SIMD8(repeating: nonEqualValue4), epsilon: epsilon)) + XCTAssertTrue(SIMD16(repeating: nonEqualValue3).isApproximatelyEqual(to: SIMD16(repeating: nonEqualValue4), epsilon: epsilon)) + XCTAssertTrue(SIMD32(repeating: nonEqualValue3).isApproximatelyEqual(to: SIMD32(repeating: nonEqualValue4), epsilon: epsilon)) + XCTAssertTrue(SIMD64(repeating: nonEqualValue3).isApproximatelyEqual(to: SIMD64(repeating: nonEqualValue4), epsilon: epsilon)) } // MARK: - SIMDRepresentable Tests @@ -72,42 +72,42 @@ final class MotionTests: XCTestCase { func testSIMDRepresentableScalarTypes() { let a: Float = 10.0 let simdA = a.simdRepresentation() - XCTAssertTrue(a.approximatelyEqual(to: simdA[0])) - XCTAssertTrue(simdA[1].approximatelyEqual(to: 0.0)) + XCTAssertTrue(a.isApproximatelyEqual(to: simdA[0])) + XCTAssertTrue(simdA[1].isApproximatelyEqual(to: 0.0)) let b: Double = 20.0 let simdB = b.simdRepresentation() - XCTAssertTrue(b.approximatelyEqual(to: simdB[0])) - XCTAssertTrue(simdB[1].approximatelyEqual(to: 0.0)) + XCTAssertTrue(b.isApproximatelyEqual(to: simdB[0])) + XCTAssertTrue(simdB[1].isApproximatelyEqual(to: 0.0)) let c: CGFloat = 30.0 let simdC = c.simdRepresentation() - XCTAssertTrue(c.approximatelyEqual(to: CGFloat(simdC[0]))) - XCTAssertTrue(simdC[1].approximatelyEqual(to: 0.0)) + XCTAssertTrue(c.isApproximatelyEqual(to: CGFloat(simdC[0]))) + XCTAssertTrue(simdC[1].isApproximatelyEqual(to: 0.0)) } func testSIMDRepresentableCoreGraphicsTypes() { let point = CGPoint(x: 10.0, y: 20.0) let simdPoint = point.simdRepresentation() - XCTAssertTrue(point.x.approximatelyEqual(to: CGFloat(simdPoint[0]))) - XCTAssertTrue(point.y.approximatelyEqual(to: CGFloat(simdPoint[1]))) + XCTAssertTrue(point.x.isApproximatelyEqual(to: CGFloat(simdPoint[0]))) + XCTAssertTrue(point.y.isApproximatelyEqual(to: CGFloat(simdPoint[1]))) XCTAssertEqual(point, CGPoint(simdPoint)) let size = CGSize(width: 30.0, height: 40.0) let simdSize = size.simdRepresentation() - XCTAssertTrue(size.width.approximatelyEqual(to: CGFloat(simdSize[0]))) - XCTAssertTrue(size.height.approximatelyEqual(to: CGFloat(simdSize[1]))) + XCTAssertTrue(size.width.isApproximatelyEqual(to: CGFloat(simdSize[0]))) + XCTAssertTrue(size.height.isApproximatelyEqual(to: CGFloat(simdSize[1]))) XCTAssertEqual(size, CGSize(simdSize)) let rect = CGRect(origin: point, size: size) let simdRect = rect.simdRepresentation() - XCTAssertTrue(rect.origin.x.approximatelyEqual(to: CGFloat(simdRect[0]))) - XCTAssertTrue(rect.origin.y.approximatelyEqual(to: CGFloat(simdRect[1]))) - XCTAssertTrue(rect.size.width.approximatelyEqual(to: CGFloat(simdRect[2]))) - XCTAssertTrue(rect.size.height.approximatelyEqual(to: CGFloat(simdRect[3]))) + XCTAssertTrue(rect.origin.x.isApproximatelyEqual(to: CGFloat(simdRect[0]))) + XCTAssertTrue(rect.origin.y.isApproximatelyEqual(to: CGFloat(simdRect[1]))) + XCTAssertTrue(rect.size.width.isApproximatelyEqual(to: CGFloat(simdRect[2]))) + XCTAssertTrue(rect.size.height.isApproximatelyEqual(to: CGFloat(simdRect[3]))) XCTAssertEqual(rect, CGRect(simdRect)) } @@ -204,20 +204,20 @@ final class MotionTests: XCTestCase { let nonRubberbandedValue = rubberband(insideValue, boundsSize: boundsSize, contentSize: contentSize) // Is the value within the clamped range. - XCTAssertTrue(nonRubberbandedValue.approximatelyEqual(to: insideValue)) + XCTAssertTrue(nonRubberbandedValue.isApproximatelyEqual(to: insideValue)) // Does it handle values less than the range. let rubberbandedValueNegative = rubberband(outsideValueNegative, boundsSize: boundsSize, contentSize: contentSize) - XCTAssertTrue(rubberbandedValueNegative.approximatelyEqual(to: -5.213)) + XCTAssertTrue(rubberbandedValueNegative.isApproximatelyEqual(to: -5.213)) // Does it handle values more than the range. let rubberbandedValuePositive = rubberband(outsideValuePositive, boundsSize: boundsSize, contentSize: contentSize) - XCTAssertTrue(rubberbandedValuePositive.approximatelyEqual(to: 105.213 /* value + boundsSize ~= 205.213 */)) + XCTAssertTrue(rubberbandedValuePositive.isApproximatelyEqual(to: 105.213 /* value + boundsSize ~= 205.213 */)) // Does it handle both positive and negative values correctly? let deltaNegative = abs(rubberbandedValueNegative) let deltaPositive = abs(rubberbandedValuePositive - boundsSize) - XCTAssertTrue(deltaNegative.approximatelyEqual(to: deltaPositive)) + XCTAssertTrue(deltaNegative.isApproximatelyEqual(to: deltaPositive)) } override class func tearDown() { diff --git a/Tests/MotionTests/SpringAnimationTests.swift b/Tests/MotionTests/SpringAnimationTests.swift index 65ce9345..6781250d 100644 --- a/Tests/MotionTests/SpringAnimationTests.swift +++ b/Tests/MotionTests/SpringAnimationTests.swift @@ -133,13 +133,13 @@ final class SpringAnimationTests: XCTestCase { underDampedSpring.toValue = 10.0 underDampedSpring.tick(frame: f) - XCTAssert(underDampedSpring.value.approximatelyEqual(to: 9.223)) + XCTAssert(underDampedSpring.value.isApproximatelyEqual(to: 9.223)) let criticallyDampedSpring = SpringAnimation(response: 1.0, dampingRatio: 1.0) criticallyDampedSpring.toValue = 10.0 criticallyDampedSpring.tick(frame: f) - XCTAssert(criticallyDampedSpring.value.approximatelyEqual(to: 8.210)) + XCTAssert(criticallyDampedSpring.value.isApproximatelyEqual(to: 8.210)) let overDampedSpring = SpringAnimation(stiffness: 2.0, damping: 10.0) overDampedSpring.toValue = 10.0 @@ -262,7 +262,7 @@ final class SpringAnimationTests: XCTestCase { XCTAssertEqual(keyframeAnimation.calculationMode, .discrete) XCTAssertFalse(keyframeAnimation.values?.isEmpty ?? true) XCTAssertFalse(keyframeAnimation.keyTimes?.isEmpty ?? true) - XCTAssertTrue(keyframeAnimation.duration.approximatelyEqual(to: 2.3999)) + XCTAssertTrue(keyframeAnimation.duration.isApproximatelyEqual(to: 2.3999)) } override class func tearDown() {