Updated property didSet to perform synchronous view layout via layoutIfNeeded instead of async setNeedsLayout. Tests use a Host now for UIEvent to trigger. Added more test cases.

This commit is contained in:
Jonathan Cardasis 2019-09-08 16:44:15 -04:00
parent fb0d1e8462
commit 5046808248
12 changed files with 440 additions and 29 deletions

View File

@ -30,6 +30,9 @@
FCE07C01227B4C8B00920217 /* UIColor+TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C00227B4C8B00920217 /* UIColor+TestHelpers.swift */; };
FCE07C04227B4DB900920217 /* UIView+DropShadowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C03227B4DB900920217 /* UIView+DropShadowTests.swift */; };
FCE07C06227B525000920217 /* ChromaControlStylableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C05227B525000920217 /* ChromaControlStylableTests.swift */; };
FCE07C08228A0F5C00920217 /* SliderTrackViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C07228A0F5C00920217 /* SliderTrackViewTests.swift */; };
FCE07C0A228A0F6800920217 /* SliderHandleViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C09228A0F6800920217 /* SliderHandleViewTests.swift */; };
FCE07C0C228A0F7500920217 /* ChromaColorHandleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C0B228A0F7500920217 /* ChromaColorHandleTests.swift */; };
FCEA4E272235AAA200C0A1B6 /* ChromaColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEA4E262235AAA200C0A1B6 /* ChromaColorPicker.swift */; };
/* End PBXBuildFile section */
@ -48,6 +51,13 @@
remoteGlobalIDString = 3503B82E1F2689BC00750356;
remoteInfo = ChromaColorPicker;
};
FC89B7DD2325706E00D007AB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 35C376C51D5CF5300069D7A1 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 35C376CC1D5CF5300069D7A1;
remoteInfo = Example;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@ -91,6 +101,9 @@
FCE07C00227B4C8B00920217 /* UIColor+TestHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+TestHelpers.swift"; sourceTree = "<group>"; };
FCE07C03227B4DB900920217 /* UIView+DropShadowTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+DropShadowTests.swift"; sourceTree = "<group>"; };
FCE07C05227B525000920217 /* ChromaControlStylableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaControlStylableTests.swift; sourceTree = "<group>"; };
FCE07C07228A0F5C00920217 /* SliderTrackViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderTrackViewTests.swift; sourceTree = "<group>"; };
FCE07C09228A0F6800920217 /* SliderHandleViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderHandleViewTests.swift; sourceTree = "<group>"; };
FCE07C0B228A0F7500920217 /* ChromaColorHandleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaColorHandleTests.swift; sourceTree = "<group>"; };
FCEA4E262235AAA200C0A1B6 /* ChromaColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaColorPicker.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -222,6 +235,9 @@
FCE07C02227B4D9500920217 /* Helpers */ = {
isa = PBXGroup;
children = (
FCE07C0B228A0F7500920217 /* ChromaColorHandleTests.swift */,
FCE07C09228A0F6800920217 /* SliderHandleViewTests.swift */,
FCE07C07228A0F5C00920217 /* SliderTrackViewTests.swift */,
);
path = Helpers;
sourceTree = "<group>";
@ -289,6 +305,7 @@
);
dependencies = (
FC1BD8C42207D7B700817AF3 /* PBXTargetDependency */,
FC89B7DE2325706E00D007AB /* PBXTargetDependency */,
);
name = ChromaColorPickerTests;
productName = ChromaColorPickerTests;
@ -319,6 +336,7 @@
CreatedOnToolsVersion = 10.1;
DevelopmentTeam = 9H97MWKJ22;
ProvisioningStyle = Automatic;
TestTargetID = 35C376CC1D5CF5300069D7A1;
};
};
};
@ -401,8 +419,11 @@
buildActionMask = 2147483647;
files = (
FCE07C06227B525000920217 /* ChromaControlStylableTests.swift in Sources */,
FCE07C0C228A0F7500920217 /* ChromaColorHandleTests.swift in Sources */,
FC1BD8C02207D7B700817AF3 /* ChromaColorPickerTests.swift in Sources */,
FCE07BFE227B4A8100920217 /* UIColor+BrightnessTests.swift in Sources */,
FCE07C0A228A0F6800920217 /* SliderHandleViewTests.swift in Sources */,
FCE07C08228A0F5C00920217 /* SliderTrackViewTests.swift in Sources */,
FC4387C422603AE900F739F1 /* ColorWheelViewTests.swift in Sources */,
FCE07C01227B4C8B00920217 /* UIColor+TestHelpers.swift in Sources */,
FCE07C04227B4DB900920217 /* UIView+DropShadowTests.swift in Sources */,
@ -422,6 +443,11 @@
target = 3503B82E1F2689BC00750356 /* ChromaColorPicker */;
targetProxy = FC1BD8C32207D7B700817AF3 /* PBXContainerItemProxy */;
};
FC89B7DE2325706E00D007AB /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 35C376CC1D5CF5300069D7A1 /* Example */;
targetProxy = FC89B7DD2325706E00D007AB /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@ -661,6 +687,7 @@
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ChromaColorPickerExample.app/ChromaColorPickerExample";
};
name = Debug;
};
@ -685,6 +712,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ChromaColorPickerExample.app/ChromaColorPickerExample";
};
name = Release;
};

View File

@ -1,3 +1,4 @@
source "https://rubygems.org"
gem "fastlane"
gem "cocoapods"

View File

@ -2,11 +2,49 @@ GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.0)
activesupport (4.2.8)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
atomos (0.1.3)
babosa (1.0.2)
claide (1.0.2)
cocoapods (1.6.1)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.6.1)
cocoapods-deintegrate (>= 1.0.2, < 2.0)
cocoapods-downloader (>= 1.2.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.3.1, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.2.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.8.1, < 2.0)
cocoapods-core (1.6.1)
activesupport (>= 4.0.2, < 6)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.2.2)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.0.0)
cocoapods-trunk (1.3.1)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.1.0)
colored (1.2)
colored2 (3.1.2)
commander-fastlane (4.4.6)
@ -18,6 +56,7 @@ GEM
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.2)
emoji_regex (1.0.1)
escape (0.0.4)
excon (0.64.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
@ -64,6 +103,8 @@ GEM
xcodeproj (>= 1.8.1, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
fourflusher (2.2.0)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
google-api-client (0.23.9)
addressable (~> 2.5, >= 2.5.1)
@ -93,6 +134,7 @@ GEM
http-cookie (1.0.3)
domain_name (~> 0.5)
httpclient (2.8.3)
i18n (0.8.1)
json (2.2.0)
jwt (2.1.0)
memoist (0.16.0)
@ -100,11 +142,15 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2019.0331)
mini_magick (4.5.1)
minitest (5.10.1)
molinillo (0.6.6)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
nanaimo (0.2.6)
nap (1.1.0)
naturally (2.2.0)
netrc (0.11.0)
os (1.0.0)
plist (3.5.0)
public_suffix (2.0.5)
@ -114,6 +160,7 @@ GEM
uber (< 0.2.0)
retriable (3.1.2)
rouge (2.0.7)
ruby-macho (1.4.0)
rubyzip (1.2.2)
security (0.1.3)
signet (0.11.0)
@ -128,10 +175,13 @@ GEM
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
tty-cursor (0.6.1)
tty-screen (0.6.5)
tty-spinner (0.9.0)
tty-cursor (~> 0.6.0)
tzinfo (1.2.3)
thread_safe (~> 0.1)
uber (0.1.0)
unf (0.1.4)
unf_ext
@ -153,6 +203,7 @@ PLATFORMS
ruby
DEPENDENCIES
cocoapods
fastlane
BUNDLED WITH

View File

@ -27,23 +27,8 @@ let brightnessSlider = ChromaBrightnessSlider(frame: CGRect(x: 0, y: 0, width: 2
addSubview(brightnessSlider)
colorPicker.connect(brightnessSlider) // or `brightnessSlider.connect(to: colorPicker)`
```
## Installation
### Carthage
```bash
github "joncardasis/ChromaColorPicker"
```
### Cocoapods
```bash
pod 'ChromaColorPicker'
```
### Manually
Add all files from the `Source` folder to your project.
## Usage
### Multiple Handles
```Swift
@ -57,6 +42,21 @@ Add all files from the `Source` folder to your project.
{TODO}
```
### Supported UIControlEvents
## Installation
### Carthage
```bash
github "joncardasis/ChromaColorPicker"
```
### Cocoapods
```bash
pod 'ChromaColorPicker'
```
### Manually
Add all files from the `Source` folder to your project.
## Components
### ChromaColorPicker
An HSB color picker with support for adding multiple color selection handles.
@ -65,6 +65,17 @@ An HSB color picker with support for adding multiple color selection handles.
[ChromaBrightnessSlider]() is a slider UIControl which can be attached to any `ChromaColorPicker` via the `connect(to:)` method. ChromaBrightnessSlider can also function as a stand-alone UIControl.
### Supported UIControlEvents
You can observe on the following UIControlEvents via `UIControl`'s `addTarget` method:
```Swift
addTarget(self, action: #selector(sliderDidValueChange(_:)), for: .valueChanged)
@objc func sliderDidValueChange(_ slider: ChromaBrightnessSlider) {
print("new color: \(slider.currentColor)")
}
```
_ChromaColorPicker_
| Event | Description |
| :-----------------:|:-------------|
| `.touchDown` | Called when a handle is first grabbed. |
@ -73,6 +84,12 @@ An HSB color picker with support for adding multiple color selection handles.
| `.touchDragInside` | Called when a handle has moved via a drag action. |
| `.editingDidEnd` | Called when either a handle is let go or slider is let go. |
_ChromaBrightnessSlider_
| Event | Description |
| :-----------------:|:-------------|
| `.valueChanged` | Called whenever the slider is moved and the value has changed. |
| `.editingDidEnd` | Called when the slider handle is released. |
##### Example
```Swift
```

View File

@ -29,15 +29,15 @@ public class ChromaBrightnessSlider: UIControl, ChromaControlStylable {
public let handle = SliderHandleView()
public var borderWidth: CGFloat = 4.0 {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
public var borderColor: UIColor = .white {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
public var showsShadow: Bool = true {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
//MARK: - Initialization

View File

@ -21,15 +21,15 @@ public class ChromaColorPicker: UIControl, ChromaControlStylable {
public weak var delegate: ChromaColorPickerDelegate?
@IBInspectable public var borderWidth: CGFloat = 6.0 {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
@IBInspectable public var borderColor: UIColor = .white {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
@IBInspectable public var showsShadow: Bool = true {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
/// A brightness slider attached via the `connect(_:)` method.
@ -41,7 +41,7 @@ public class ChromaColorPicker: UIControl, ChromaControlStylable {
/// The size handles should be displayed at.
public var handleSize: CGSize = defaultHandleSize {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
/// An extension to handles' hitboxes in the +Y direction.

View File

@ -12,7 +12,7 @@ public class ChromaColorHandle: UIView, ChromaControlStylable {
/// Current selected color of the handle.
public var color: UIColor = .black {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
/// An image to display in the handle. Updates `accessoryView` to be a UIImageView.
@ -36,19 +36,19 @@ public class ChromaColorHandle: UIView, ChromaControlStylable {
/// The amount an accessory view's frame should be inset by.
public var accessoryViewEdgeInsets: UIEdgeInsets = .zero {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
public var borderWidth: CGFloat = 3.0 {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
public var borderColor: UIColor = .white {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
public var showsShadow: Bool = true {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
// MARK: - Initialization

View File

@ -15,11 +15,11 @@ public class SliderHandleView: UIView {
}
public var borderWidth: CGFloat = 3.0 {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
public var borderColor: UIColor = .white {
didSet { setNeedsLayout() }
didSet { layoutIfNeeded() }
}
override public init(frame: CGRect) {

View File

@ -16,6 +16,50 @@ class ChromaColorPickerTests: XCTestCase {
subject = ChromaColorPicker(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
}
// MARK: Handles
func testAddHandleAddsHandleToArray() {
// Given, When
subject.addHandle()
// Then
XCTAssertEqual(subject.handles.count, 1)
}
func testAddHandleAddsCustomHandleToArray() {
// Given
let handle = ChromaColorHandle(color: .black)
// When
subject.addHandle(handle)
// Then
XCTAssertEqual(subject.handles.first!, handle)
}
func testAddHandlePlacesHandleAtWhiteIfColorIsNil() {
// Given, When
subject.addHandle(at: nil)
// Then
XCTAssertEqual(subject.handles.first!.color, .white)
}
func testAddHandleUpdatesBrightnessSliderIfAttached() {
// Given
let slider = ChromaBrightnessSlider(frame: .zero)
subject.connect(slider)
let color: UIColor = .purple
// When
subject.addHandle(at: color)
// Then
XCTAssertEqual(slider.trackColor, color)
}
// MARK: Brightness Slider
func testConnectingSliderAddsEventTarget() {
// Given
let slider = ChromaBrightnessSlider(frame: .zero)
@ -41,4 +85,156 @@ class ChromaColorPickerTests: XCTestCase {
// Then
XCTAssertEqual(slider1.allTargets.count, 0)
}
// MARK: UI Control
func testShouldBeginTrackingAndSetCurrentHandleIfTouchedHandle() {
// Given
let handleFrame = CGRect(x: subject.bounds.width / 2.0, y: subject.bounds.height / 2.0, width: 10, height: 10)
let handle = ChromaColorHandle(frame: handleFrame)
subject.addHandle(handle)
let fakeTouch = FakeUITouch(locationInParent: handleFrame.origin)
// When
let result = subject.beginTracking(fakeTouch, with: nil)
// Then
XCTAssertTrue(result)
XCTAssertEqual(subject.currentHandle, handle)
}
func testShouldBeginTrackingIfTouchedOnHandleWithExtendedHitBox() {
// Given
let yExtension: CGFloat = 8.0
let handleFrame = CGRect(x: subject.bounds.width / 2.0, y: subject.bounds.height / 2.0, width: 10, height: 10)
subject.addHandle(ChromaColorHandle(frame: handleFrame))
subject.handleHitboxExtensionY = yExtension
let fakeTouch = FakeUITouch(locationInParent: CGPoint(x: handleFrame.origin.x,
y: handleFrame.origin.y + handleFrame.height + yExtension - 1))
// When
let result = subject.beginTracking(fakeTouch, with: nil)
// Then
XCTAssertTrue(result)
}
func testBeginTrackingUpdatesBrightnessSliderIfAttached() {
// Given
let slider = ChromaBrightnessSlider(frame: .zero)
subject.connect(slider)
let handleFrame = CGRect(x: subject.bounds.width / 2.0, y: subject.bounds.height / 2.0, width: 10, height: 10)
let handle = ChromaColorHandle(frame: handleFrame)
subject.addHandle(handle)
let fakeTouch = FakeUITouch(locationInParent: handleFrame.origin)
// When
let _ = subject.beginTracking(fakeTouch, with: nil)
// Then
XCTAssertEqual(slider.trackColor, handle.color.withBrightness(1))
XCTAssertEqual(slider.currentValue, slider.value(brightness: handle.color.brightness))
}
func testStopContinueTrackingIfCurrentHandleIsNil() {
// Given, When
let result = subject.continueTracking(FakeUITouch(locationInParent: .zero), with: nil)
// Then
XCTAssertNil(subject.currentHandle)
XCTAssertFalse(result)
}
func testContinueTrackingSendsValueChangedActionForValidLocation() {
subject.colorWheelView.layoutIfNeeded()
// Given
setCurrentHandle(to: makeFakeHandle())
let fakeTouch = FakeUITouch(locationInParent: CGPoint(x: subject.colorWheelView.bounds.midX,
y: subject.colorWheelView.bounds.midY))
let eventReceiver = FakeEventReceiver()
subject.addTarget(eventReceiver, action: #selector(FakeEventReceiver.catchEvent), for: .valueChanged)
let expectation = XCTestExpectation(description: "event fired")
eventReceiver.eventCaught = { event in
if event == .valueChanged {
expectation.fulfill()
} else {
XCTFail()
}
}
// When
let _ = subject.continueTracking(fakeTouch, with: nil)
// Then
wait(for: [expectation], timeout: 0.05)
}
func testEndTrackingSendsEditingDidEndAction() {
subject.colorWheelView.layoutIfNeeded()
// Given
setCurrentHandle(to: makeFakeHandle())
let fakeTouch = FakeUITouch(locationInParent: CGPoint(x: subject.colorWheelView.bounds.midX,
y: subject.colorWheelView.bounds.midY))
let eventReceiver = FakeEventReceiver()
subject.addTarget(eventReceiver, action: #selector(FakeEventReceiver.catchEvent), for: .editingDidEnd)
let expectation = XCTestExpectation(description: "event fired")
eventReceiver.eventCaught = { event in
if event == .valueChanged {
expectation.fulfill()
} else {
XCTFail()
}
}
// When
let _ = subject.endTracking(fakeTouch, with: nil)
// Then
wait(for: [expectation], timeout: 0.05)
}
}
// Test Helpers
extension ChromaColorPickerTests {
func makeFakeHandle() -> ChromaColorHandle {
return ChromaColorHandle(frame: CGRect(x: subject.bounds.midX, y: subject.bounds.midY, width: 10, height: 10))
}
func setCurrentHandle(to handle: ChromaColorHandle) {
subject.addHandle(handle)
let fakeTouch = FakeUITouch(locationInParent: handle.frame.origin)
let _ = subject.beginTracking(fakeTouch, with: nil)
}
}
private class FakeUITouch: UITouch {
let locationInParent: CGPoint
init(locationInParent: CGPoint) {
self.locationInParent = locationInParent
}
override func location(in view: UIView?) -> CGPoint {
return locationInParent
}
}
private class FakeEventReceiver: NSObject {
var eventCaught: ((UIControl.Event) -> ())?
@objc func catchEvent() {
eventCaught?(.valueChanged)
}
}

View File

@ -0,0 +1,50 @@
//
// ChromaColorHandleTests.swift
// ChromaColorPickerTests
//
// Created by Jon Cardasis on 5/13/19.
// Copyright © 2019 Jonathan Cardasis. All rights reserved.
//
import XCTest
@testable import ChromaColorPicker
class ChromaColorHandleTests: XCTestCase {
func testSettingAcessoryImageMakesAccessoryViewUIImageView() {
// Given
let subject = ChromaColorHandle()
// When
subject.accessoryImage = UIImage()
// Then
XCTAssertNotNil(subject.accessoryView)
XCTAssertTrue(subject.accessoryView is UIImageView)
}
func testSettingAccessoryImageMakesImageViewAspectFit() {
// Given
let subject = ChromaColorHandle()
// When
subject.accessoryImage = UIImage()
// Then
XCTAssertEqual(subject.accessoryView!.contentMode, .scaleAspectFit)
}
func testSettingAccessoryViewOverridesImage() {
// Given
let subject = ChromaColorHandle()
subject.accessoryImage = UIImage()
let view = UIView()
// When
subject.accessoryView = view
// Then
XCTAssertEqual(subject.accessoryView, view)
}
}

View File

@ -0,0 +1,59 @@
//
// SliderHandleViewTests.swift
// ChromaColorPickerTests
//
// Created by Jon Cardasis on 5/13/19.
// Copyright © 2019 Jonathan Cardasis. All rights reserved.
//
import XCTest
@testable import ChromaColorPicker
class SliderHandleViewTests: XCTestCase {
func testSettingHandleColorUpdatesHandleLayer() {
// Given
let subject = SliderHandleView()
let layer = handleLayer(for: subject)
let expectedColor: UIColor = .purple
// When
subject.handleColor = expectedColor
// Then
XCTAssertEqual(layer.fillColor!, expectedColor.cgColor)
}
func testSettingBorderColorUpdatesHandleLayer() {
// Given
let subject = SliderHandleView()
let layer = handleLayer(for: subject)
let expectedColor: UIColor = .purple
// When
subject.borderColor = expectedColor
// Then
XCTAssertEqual(layer.strokeColor!, expectedColor.cgColor);
}
func testSettingBorderWidthUpdatesHandleLayer() {
// Given
let subject = SliderHandleView()
let layer = handleLayer(for: subject)
let expectedWidth: CGFloat = 12.0
// When
subject.borderWidth = expectedWidth
// Then
XCTAssertEqual(layer.lineWidth, expectedWidth);
}
}
/// Return the internal cashape sublayer for the provided view.
fileprivate func handleLayer(for handleView: SliderHandleView) -> CAShapeLayer {
return handleView.layer.sublayers!.first(where: { $0 is CAShapeLayer }) as! CAShapeLayer
}

View File

@ -0,0 +1,9 @@
//
// SliderTrackViewTests.swift
// ChromaColorPickerTests
//
// Created by Jon Cardasis on 5/13/19.
// Copyright © 2019 Jonathan Cardasis. All rights reserved.
//
import Foundation