mirror of
https://github.com/joncardasis/ChromaColorPicker.git
synced 2024-11-22 06:32:06 +03:00
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:
parent
fb0d1e8462
commit
5046808248
@ -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;
|
||||
};
|
||||
|
51
Gemfile.lock
51
Gemfile.lock
@ -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
|
||||
|
47
README.md
47
README.md
@ -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
|
||||
```
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
50
Tests/Helpers/ChromaColorHandleTests.swift
Normal file
50
Tests/Helpers/ChromaColorHandleTests.swift
Normal 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)
|
||||
}
|
||||
|
||||
}
|
59
Tests/Helpers/SliderHandleViewTests.swift
Normal file
59
Tests/Helpers/SliderHandleViewTests.swift
Normal 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
|
||||
}
|
||||
|
9
Tests/Helpers/SliderTrackViewTests.swift
Normal file
9
Tests/Helpers/SliderTrackViewTests.swift
Normal 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
|
Loading…
Reference in New Issue
Block a user