mirror of
https://github.com/wnagrodzki/UserInterfaceVariations.git
synced 2025-05-03 17:21:40 +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