mirror of
https://github.com/wnagrodzki/UserInterfaceVariations.git
synced 2025-05-07 03:01:41 +02:00
Add UIVariationEnvironment and unit tests
This commit is contained in:
parent
008ae67343
commit
677cf799f1
2 changed files with 173 additions and 0 deletions
72
Sources/UserInterfaceVariations/UIVariationEnvironment.swift
Normal file
72
Sources/UserInterfaceVariations/UIVariationEnvironment.swift
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public protocol UIVariationEnvironment { }
|
||||||
|
|
||||||
|
extension UIVariationEnvironment where Self: UITraitEnvironment {
|
||||||
|
|
||||||
|
public var variations: NSMutableArray {
|
||||||
|
get {
|
||||||
|
let key = Unmanaged.passUnretained(association).toOpaque()
|
||||||
|
if let array = objc_getAssociatedObject(self, key) as! NSMutableArray? { return array }
|
||||||
|
let array = NSMutableArray()
|
||||||
|
objc_setAssociatedObject(self, key, array, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||||
|
return array
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addVariation<Object, Value>(_ variation: UIVariation<Object, Value>) {
|
||||||
|
variation.traitEnvironment = self
|
||||||
|
variations.add(variation)
|
||||||
|
variation.applyIfMatchesTraitEnvironment()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func removeVariation<Object, Value>(_ variation: UIVariation<Object, Value>) {
|
||||||
|
variations.remove(variation)
|
||||||
|
variation.traitEnvironment = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
public func addVariation<Object: AnyObject, Value>(for object: Object,
|
||||||
|
property: ReferenceWritableKeyPath<Object, Value>,
|
||||||
|
sizeClassDimension: SizeClassDimension,
|
||||||
|
whenCompact: Value) {
|
||||||
|
switch sizeClassDimension {
|
||||||
|
case .horizontal:
|
||||||
|
addVariation(UIVariation<Object, Value>(object: object,
|
||||||
|
keyPath: property,
|
||||||
|
value: object[keyPath: property],
|
||||||
|
horizontalSizeClass: .regular,
|
||||||
|
verticalSizeClass: nil))
|
||||||
|
addVariation(UIVariation<Object, Value>(object: object,
|
||||||
|
keyPath: property,
|
||||||
|
value: whenCompact,
|
||||||
|
horizontalSizeClass: .compact,
|
||||||
|
verticalSizeClass: nil))
|
||||||
|
case .vertical:
|
||||||
|
addVariation(UIVariation<Object, Value>(object: object,
|
||||||
|
keyPath: property,
|
||||||
|
value: object[keyPath: property],
|
||||||
|
horizontalSizeClass: nil,
|
||||||
|
verticalSizeClass: .regular))
|
||||||
|
addVariation(UIVariation<Object, Value>(object: object,
|
||||||
|
keyPath: property,
|
||||||
|
value: whenCompact,
|
||||||
|
horizontalSizeClass: nil,
|
||||||
|
verticalSizeClass: .compact))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call this method when trait collection changes to keep variations reacting to them.
|
||||||
|
///
|
||||||
|
/// override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||||
|
/// super.traitCollectionDidChange(previousTraitCollection)
|
||||||
|
/// activateVariationsMatchingTraitEnvironment()
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
public func activateVariationsMatchingTraitEnvironment() {
|
||||||
|
for variation in variations as! [UIVariationApplying] {
|
||||||
|
variation.applyIfMatchesTraitEnvironment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private let association = NSObject()
|
|
@ -0,0 +1,101 @@
|
||||||
|
import XCTest
|
||||||
|
@testable import UserInterfaceVariations
|
||||||
|
|
||||||
|
final class UIVariationEnvironmentTests: XCTestCase {
|
||||||
|
|
||||||
|
let label = UILabel()
|
||||||
|
let valueWhenCompact = "value when compact"
|
||||||
|
let valueWhenRegular = "value when regular"
|
||||||
|
|
||||||
|
override func setUp() {
|
||||||
|
label.text = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_When_variation_matches_traitEnvironment_Then_it_is_applied() {
|
||||||
|
let variationEnvironment = UIVariationEnvironmentFake(traitCollection: UITraitCollection(horizontalSizeClass: .compact))
|
||||||
|
let variation = UIVariation(object: label,
|
||||||
|
keyPath: \.text,
|
||||||
|
value: valueWhenCompact,
|
||||||
|
horizontalSizeClass: .compact,
|
||||||
|
verticalSizeClass: nil)
|
||||||
|
variationEnvironment.addVariation(variation)
|
||||||
|
XCTAssertEqual(label.text, variation.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_adding_variation_convenience_method_for_sizeClassDimension_horizontal() {
|
||||||
|
label.text = valueWhenRegular
|
||||||
|
|
||||||
|
let variationEnvironment = UIVariationEnvironmentFake(traitCollection: UITraitCollection(horizontalSizeClass: .regular))
|
||||||
|
variationEnvironment.addVariation(for: label,
|
||||||
|
property: \.text,
|
||||||
|
sizeClassDimension: .horizontal,
|
||||||
|
whenCompact: valueWhenCompact)
|
||||||
|
|
||||||
|
let variation0 = variationEnvironment.variations[0] as! UIVariation<UILabel, String?>
|
||||||
|
XCTAssertTrue(variation0.object === label)
|
||||||
|
XCTAssertTrue(variation0.property == \.text)
|
||||||
|
XCTAssertTrue(variation0.value == valueWhenRegular)
|
||||||
|
XCTAssertTrue(variation0.horizontalSizeClass == .regular)
|
||||||
|
XCTAssertTrue(variation0.verticalSizeClass == nil)
|
||||||
|
|
||||||
|
let variation1 = variationEnvironment.variations[1] as! UIVariation<UILabel, String?>
|
||||||
|
XCTAssertTrue(variation1.object === label)
|
||||||
|
XCTAssertTrue(variation1.property == \.text)
|
||||||
|
XCTAssertTrue(variation1.value == valueWhenCompact)
|
||||||
|
XCTAssertTrue(variation1.horizontalSizeClass == .compact)
|
||||||
|
XCTAssertTrue(variation1.verticalSizeClass == nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_adding_variation_convenience_method_for_sizeClassDimension_vartical() {
|
||||||
|
label.text = valueWhenRegular
|
||||||
|
|
||||||
|
let variationEnvironment = UIVariationEnvironmentFake(traitCollection: UITraitCollection(horizontalSizeClass: .regular))
|
||||||
|
variationEnvironment.addVariation(for: label,
|
||||||
|
property: \.text,
|
||||||
|
sizeClassDimension: .vertical,
|
||||||
|
whenCompact: valueWhenCompact)
|
||||||
|
|
||||||
|
let variation0 = variationEnvironment.variations[0] as! UIVariation<UILabel, String?>
|
||||||
|
XCTAssertTrue(variation0.object === label)
|
||||||
|
XCTAssertTrue(variation0.property == \.text)
|
||||||
|
XCTAssertTrue(variation0.value == valueWhenRegular)
|
||||||
|
XCTAssertTrue(variation0.horizontalSizeClass == nil)
|
||||||
|
XCTAssertTrue(variation0.verticalSizeClass == .regular)
|
||||||
|
|
||||||
|
let variation1 = variationEnvironment.variations[1] as! UIVariation<UILabel, String?>
|
||||||
|
XCTAssertTrue(variation1.object === label)
|
||||||
|
XCTAssertTrue(variation1.property == \.text)
|
||||||
|
XCTAssertTrue(variation1.value == valueWhenCompact)
|
||||||
|
XCTAssertTrue(variation1.horizontalSizeClass == nil)
|
||||||
|
XCTAssertTrue(variation1.verticalSizeClass == .compact)
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_When_verticalSizeClass_in_traitCollection_changes_Then_variation_is_applied() {
|
||||||
|
let variationEnvironment = UIVariationEnvironmentFake(traitCollection: UITraitCollection(verticalSizeClass: .regular))
|
||||||
|
label.text = valueWhenRegular
|
||||||
|
variationEnvironment.addVariation(for: label,
|
||||||
|
property: \.text,
|
||||||
|
sizeClassDimension: .vertical,
|
||||||
|
whenCompact: valueWhenCompact)
|
||||||
|
variationEnvironment.traitCollection = UITraitCollection(verticalSizeClass: .compact)
|
||||||
|
XCTAssertEqual(label.text, valueWhenCompact)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UIVariationEnvironmentFake: NSObject, UITraitEnvironment {
|
||||||
|
|
||||||
|
var traitCollection = UITraitCollection() {
|
||||||
|
didSet { traitCollectionDidChange(oldValue) }
|
||||||
|
}
|
||||||
|
|
||||||
|
init(traitCollection: UITraitCollection) {
|
||||||
|
self.traitCollection = traitCollection
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||||
|
activateVariationsMatchingTraitEnvironment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UIVariationEnvironmentFake: UIVariationEnvironment { }
|
Loading…
Add table
Reference in a new issue