diff --git a/.github/workflows/cocoapods.yml b/.github/workflows/cocoapods.yml deleted file mode 100644 index 6df4f020..00000000 --- a/.github/workflows/cocoapods.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: CocoaPods - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -env: - DEVELOPER_DIR: /Applications/Xcode_14.3.app/Contents/Developer - -jobs: - cocoapods: - name: CocoaPods - runs-on: macos-13 - steps: - - name: Checkout source - uses: actions/checkout@v3 - - name: Lint - run: pod lib lint --skip-tests --verbose Layout.podspec diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 1761e38b..2e1d39d9 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -36,6 +36,8 @@ jobs: DIRECTORY_NAME=$(echo "${PWD##*/}" | tr '[:upper:]' '[:lower:]') "$(find ".build/artifacts/${DIRECTORY_NAME}" -type f -name swiftlint -perm +111 -print -quit)" \ lint --strict --reporter github-actions-logging + - name: Resolve package dependencies + run: xcodebuild -resolvePackageDependencies - name: Build run: xcodebuild build-for-testing -scheme "Layout" -destination "name=$SIMULATOR,OS=latest" - name: Run tests diff --git a/Layout.podspec b/Layout.podspec deleted file mode 100644 index d459392d..00000000 --- a/Layout.podspec +++ /dev/null @@ -1,22 +0,0 @@ -Pod::Spec.new do |s| - s.name = 'Layout' - s.version = '0.0.0' - s.summary = 'Tinder\'s UIKit Auto Layout API' - s.description = 'An API for adding subviews and constraints to a view.' - s.homepage = 'https://github.com/Tinder/Layout' - s.license = { :type => 'Modified 3-Clause BSD License', :file => 'LICENSE' } - s.author = { 'Tinder' => 'info@gotinder.com' } - s.source = { :git => 'https://github.com/Tinder/Layout.git', :tag => s.version } - s.social_media_url = 'https://twitter.com/TinderEng' - - s.ios.deployment_target = '13.0' - s.swift_version = '5.5', '5.6', '5.7' - s.source_files = 'Sources/Layout/**/*' - - s.test_spec 'Tests' do |t| - t.source_files = 'Tests/LayoutTests/**/*' - - t.dependency 'Nimble', '11.2' - t.dependency 'SnapshotTesting', '1.9' - end -end diff --git a/README.md b/README.md index e68cd9bd..a443dfa6 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,6 @@   [![Bazel](https://github.com/Tinder/Layout/actions/workflows/bazel.yml/badge.svg?event=push)](https://github.com/Tinder/Layout/actions/workflows/bazel.yml)   -[![CocoaPods](https://github.com/Tinder/Layout/actions/workflows/cocoapods.yml/badge.svg?event=push)](https://github.com/Tinder/Layout/actions/workflows/cocoapods.yml) -  [![Artifactory](https://github.com/Tinder/Layout/actions/workflows/artifactory.yml/badge.svg?event=push)](https://github.com/Tinder/Layout/actions/workflows/artifactory.yml) # Layout diff --git a/Sources/Layout/LayoutItem.swift b/Sources/Layout/LayoutItem.swift index 316ff02b..b9f95079 100644 --- a/Sources/Layout/LayoutItem.swift +++ b/Sources/Layout/LayoutItem.swift @@ -203,6 +203,95 @@ extension LayoutItem { to(axis.attribute, multiplier: multiplier, constant: offset, priority: priority) } + /// Vertically centers the view between two anchors. + /// + /// - Parameters: + /// - between: the top layout anchor (1) + /// - and: the bottom layout anchor (2) + /// - Example: + /// ``` + /// view.layout( + /// label + /// .to(.centerX) + /// .center(between: view.safeAreaLayoutGuide.top, and: siblingView.top), + /// siblingView.center() + /// ).activate() + /// + /// +---------(1)---------+ + /// | | + /// | label | + /// | | + /// | +--(2)--+ | + /// | | | | + /// | | | | + /// | | | | + /// | +-------+ | + /// | | + /// | | + /// +---------------------+ + /// ``` + public func center( + between top: NSLayoutYAxisAnchor, + and bottom: NSLayoutYAxisAnchor + ) -> LayoutItem { + addingSuperviewConstraints { layoutItem in + if let superview = layoutItem.layoutItemView.superview { + let guide: UILayoutGuide = { + let guide: UILayoutGuide = .init() + superview.addLayoutGuide(guide) + return guide + }() + guide.top.constraint(to: top) + guide.bottom.constraint(to: bottom) + layoutItem.layoutItemView.centerY.constraint(to: guide.centerY) + } + } + } + + /// Horizontally centers the view between two anchors. + /// + /// - Parameters: + /// - between: the leading layout anchor (1) + /// - and: the trailing layout anchor (2) + /// - Example: + /// ``` + /// view.layout( + /// label + /// .to(.centerY) + /// .center(between: siblingView.trailing, and: view.safeAreaLayoutGuide.trailing), + /// siblingView.center().square(50) + /// ).activate() + /// + /// +------------------------------+ + /// | | + /// | | + /// | +------+ | + /// | | | | + /// | | (1) label (2) + /// | | | | + /// | +------+ | + /// | | + /// | | + /// +------------------------------+ + /// ``` + public func center( + between leading: NSLayoutXAxisAnchor, + and trailing: NSLayoutXAxisAnchor + ) -> LayoutItem { + addingSuperviewConstraints { layoutItem in + if let superview = layoutItem.layoutItemView.superview { + let guide: UILayoutGuide = { + let guide: UILayoutGuide = .init() + superview.addLayoutGuide(guide) + return guide + }() + guide.leading.constraint(to: leading) + guide.trailing.constraint(to: trailing) + layoutItem.layoutItemView.centerX.constraint(to: guide.centerX) + } + } + } + /// Constrains the `attribute` to the superview's corresponding `attribute` /// /// - Note: @@ -478,95 +567,6 @@ extension LayoutItem { } } - /// Vertically centers the view between two anchors. - /// - /// - Parameters: - /// - between: the top layout anchor (1) - /// - and: the bottom layout anchor (2) - /// - Example: - /// ``` - /// view.layout( - /// label - /// .to(.centerX) - /// .center(between: view.safeAreaLayoutGuide.top, and: siblingView.top), - /// siblingView.center() - /// ).activate() - /// - /// +---------(1)---------+ - /// | | - /// | label | - /// | | - /// | +--(2)--+ | - /// | | | | - /// | | | | - /// | | | | - /// | +-------+ | - /// | | - /// | | - /// +---------------------+ - /// ``` - public func center( - between top: NSLayoutYAxisAnchor, - and bottom: NSLayoutYAxisAnchor - ) -> LayoutItem { - addingSuperviewConstraints { layoutItem in - if let superview = layoutItem.layoutItemView.superview { - let guide: UILayoutGuide = { - let guide: UILayoutGuide = .init() - superview.addLayoutGuide(guide) - return guide - }() - guide.top.constraint(to: top) - guide.bottom.constraint(to: bottom) - layoutItem.layoutItemView.centerY.constraint(to: guide.centerY) - } - } - } - - /// Horizontally centers the view between two anchors. - /// - /// - Parameters: - /// - between: the leading layout anchor (1) - /// - and: the trailing layout anchor (2) - /// - Example: - /// ``` - /// view.layout( - /// label - /// .to(.centerY) - /// .center(between: siblingView.trailing, and: view.safeAreaLayoutGuide.trailing), - /// siblingView.center().square(50) - /// ).activate() - /// - /// +------------------------------+ - /// | | - /// | | - /// | +------+ | - /// | | | | - /// | | (1) label (2) - /// | | | | - /// | +------+ | - /// | | - /// | | - /// +------------------------------+ - /// ``` - public func center( - between leading: NSLayoutXAxisAnchor, - and trailing: NSLayoutXAxisAnchor - ) -> LayoutItem { - addingSuperviewConstraints { layoutItem in - if let superview = layoutItem.layoutItemView.superview { - let guide: UILayoutGuide = { - let guide: UILayoutGuide = .init() - superview.addLayoutGuide(guide) - return guide - }() - guide.leading.constraint(to: leading) - guide.trailing.constraint(to: trailing) - layoutItem.layoutItemView.centerX.constraint(to: guide.centerX) - } - } - } - /// Constrains the view's directional edges to the superview's safe area with insets. /// /// - Parameters: diff --git a/Sources/Layout/UIView+Autolayout.swift b/Sources/Layout/UIView+Autolayout.swift index 75999f7f..6c83b83e 100644 --- a/Sources/Layout/UIView+Autolayout.swift +++ b/Sources/Layout/UIView+Autolayout.swift @@ -76,14 +76,14 @@ extension UIView { public func constrain( to superview: UIView, - directionalEdgeInsets: DirectionalInsets = .zero + insets: DirectionalInsets = .zero ) { translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - leading.constraint(equalTo: superview.leading, constant: directionalEdgeInsets.leading), - trailing.constraint(equalTo: superview.trailing, constant: -directionalEdgeInsets.trailing), - top.constraint(equalTo: superview.top, constant: directionalEdgeInsets.top), - bottom.constraint(equalTo: superview.bottom, constant: -directionalEdgeInsets.bottom) + leading.constraint(equalTo: superview.leading, constant: insets.leading), + trailing.constraint(equalTo: superview.trailing, constant: -insets.trailing), + top.constraint(equalTo: superview.top, constant: insets.top), + bottom.constraint(equalTo: superview.bottom, constant: -insets.bottom) ]) } diff --git a/Tests/LayoutTests/LayoutItemTests.swift b/Tests/LayoutTests/LayoutItemTests.swift index b9534bf1..f3a492e2 100644 --- a/Tests/LayoutTests/LayoutItemTests.swift +++ b/Tests/LayoutTests/LayoutItemTests.swift @@ -45,14 +45,14 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // Size Width and Height With Default Priority + // Size Width and Height with Default Priority pinkView .to([.top, .leading]) .size(width: 150, height: 250, priority: .high) .size(width: 100, height: 200) - // Size Width and Height With Priority + // Size Width and Height with Priority yellowView .to([.top, .trailing]) @@ -66,14 +66,14 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // Size CGSize With Default Priority + // Size CGSize with Default Priority pinkView .to([.top, .leading]) .size(CGSize(width: 150, height: 250), priority: .high) .size(CGSize(width: 100, height: 200)) - // Size CGSize With Priority + // Size CGSize with Priority yellowView .to([.top, .trailing]) @@ -91,7 +91,7 @@ final class LayoutItemTests: XCTestCase { // swiftlint:disable:next closure_body_length view.layout { - // Size Width With Default Relation and Priority + // Size Width with Default Relation and Priority pinkView .to([.top, .leading]) @@ -99,7 +99,7 @@ final class LayoutItemTests: XCTestCase { .size(is: .greaterThanOrEqual, width: 100, priority: .high) .size(width: 50) - // Size Width With Priority + // Size Width with Priority yellowView .to([.top, .trailing]) @@ -107,7 +107,7 @@ final class LayoutItemTests: XCTestCase { .size(width: 1, priority: .low) .size(width: 50, priority: .high) - // Size Width With GreaterThanOrEqual Relation and Priority + // Size Width with GreaterThanOrEqual Relation and Priority blueView .to([.bottom, .leading]) @@ -115,7 +115,7 @@ final class LayoutItemTests: XCTestCase { .size(width: 40, priority: .high) .size(is: .greaterThanOrEqual, width: 50) - // Size Width With LessThanOrEqual Relation and Priority + // Size Width with LessThanOrEqual Relation and Priority greenView .to([.bottom, .trailing]) @@ -123,7 +123,7 @@ final class LayoutItemTests: XCTestCase { .size(width: 60, priority: .high) .size(is: .lessThanOrEqual, width: 50) - // Size Width With GreaterThanOrEqual Relation + // Size Width with GreaterThanOrEqual Relation redView .to(.centerY, constant: -50) @@ -132,7 +132,7 @@ final class LayoutItemTests: XCTestCase { .size(width: 60) .size(is: .greaterThanOrEqual, width: 50) - // Size Width With LessThanOrEqual Relation + // Size Width with LessThanOrEqual Relation orangeView .to(.centerY, constant: 50) @@ -152,7 +152,7 @@ final class LayoutItemTests: XCTestCase { // swiftlint:disable:next closure_body_length view.layout { - // Size Height With Default Relation and Priority + // Size Height with Default Relation and Priority pinkView .to([.top, .leading]) @@ -160,7 +160,7 @@ final class LayoutItemTests: XCTestCase { .size(is: .greaterThanOrEqual, height: 150, priority: .high) .size(height: 100) - // Size Height With Priority + // Size Height with Priority yellowView .to([.top, .trailing]) @@ -168,7 +168,7 @@ final class LayoutItemTests: XCTestCase { .size(height: 1, priority: .low) .size(height: 100, priority: .high) - // Size Height With GreaterThanOrEqual Relation + // Size Height with GreaterThanOrEqual Relation blueView .to([.bottom, .leading]) @@ -176,7 +176,7 @@ final class LayoutItemTests: XCTestCase { .size(height: 75, priority: .high) .size(is: .greaterThanOrEqual, height: 100) - // Size Height With LessThanOrEqual Relation + // Size Height with LessThanOrEqual Relation greenView .to([.bottom, .trailing]) @@ -184,7 +184,7 @@ final class LayoutItemTests: XCTestCase { .size(height: 125, priority: .high) .size(is: .lessThanOrEqual, width: 50) - // Size Height With GreaterThanOrEqual Relation and Priority + // Size Height with GreaterThanOrEqual Relation and Priority redView .to([.centerY], constant: -50) @@ -193,7 +193,7 @@ final class LayoutItemTests: XCTestCase { .size(height: 110, priority: .high) .size(is: .greaterThanOrEqual, height: 100) - // Size Height With LessThanOrEqual Relation and Priority + // Size Height with LessThanOrEqual Relation and Priority orangeView .to([.centerY], constant: 50) @@ -209,14 +209,14 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // Square With Width + // Square with Width pinkView .to([.top, .leading]) .size(width: 100) .square() - // Square With Height + // Square with Height yellowView .to([.top, .trailing]) @@ -230,14 +230,14 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // Square Length With Default Priority + // Square Length with Default Priority pinkView .to([.top, .leading]) .square(200, priority: .high) .square(100) - // Square Length With Priority + // Square Length with Priority yellowView .to([.top, .trailing]) @@ -251,7 +251,7 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // Aspect Ratio With Default Priority + // Aspect Ratio with Default Priority pinkView .to([.top, .leading]) @@ -259,7 +259,7 @@ final class LayoutItemTests: XCTestCase { .aspectRatio(0.5, priority: .high) .aspectRatio(0.75) - // Aspect Ratio With Priority + // Aspect Ratio with Priority yellowView .to([.top, .trailing]) @@ -274,20 +274,20 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // Center With Default Offset + // Center with Default Offset pinkView .size(width: 50, height: 50) .center(offset: UIOffset(horizontal: 50, vertical: 50), priority: .high) .center() - // Center With Offset + // Center with Offset yellowView .size(width: 50, height: 50) .center(offset: UIOffset(horizontal: 50, vertical: 50)) - // Center With Priority + // Center with Priority blueView .size(width: 50, height: 50) @@ -301,7 +301,7 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // Center With Vertical Axis and Default Multiplier and Priority + // Center with Vertical Axis and Default Multiplier and Priority pinkView .size(width: 100, height: 100) @@ -309,7 +309,7 @@ final class LayoutItemTests: XCTestCase { .center(.vertical, offset: 50, multiplier: 0.5, priority: .high) .center(.vertical) - // Center With Horizontal Axis and Default Multiplier and Priority + // Center with Horizontal Axis and Default Multiplier and Priority yellowView .size(width: 100, height: 100) @@ -317,21 +317,21 @@ final class LayoutItemTests: XCTestCase { .center(.horizontal, offset: 50, multiplier: 0.5, priority: .high) .center(.horizontal) - // Center With Vertical Axis and Offset + // Center with Vertical Axis and Offset blueView .size(width: 100, height: 100) .to(.leading) .center(.vertical, offset: 100) - // Center With Horizontal Axis and Multiplier + // Center with Horizontal Axis and Multiplier greenView .size(width: 100, height: 100) .to(.top) .center(.horizontal, multiplier: 1.5) - // Center With Vertical Axis and Priority + // Center with Vertical Axis and Priority orangeView .size(width: 100, height: 100) @@ -342,11 +342,33 @@ final class LayoutItemTests: XCTestCase { } } + func testCenterBetweenTopAndBottom() { + assertLayout(devices: Device.allTestDevices) { view in + view.layout( + pinkView + .size(width: 200, height: 100) + .to(.leading) + .center(between: view.safeAreaLayoutGuide.top, and: view.safeAreaLayoutGuide.bottom) + ) + } + } + + func testCenterBetweenLeadingAndTrailing() { + assertLayout(devices: Device.allTestDevices) { view in + view.layout( + pinkView + .size(width: 200, height: 100) + .to(.top) + .center(between: view.safeAreaLayoutGuide.leading, and: view.safeAreaLayoutGuide.trailing) + ) + } + } + func testToAttribute_andWithConstant_andWithMultiplier_andWithPriority() { assertLayout { view in view.layout { - // To Top Leading With Default Relation, Multiplier and Priority + // To Top Leading with Default Relation, Multiplier and Priority pinkView .size(width: 100, height: 100) @@ -355,28 +377,28 @@ final class LayoutItemTests: XCTestCase { .to(.top) .to(.leading) - // To Top Trailing With Constant + // To Top Trailing with Constant yellowView .size(width: 100, height: 100) .to(.top, constant: 25) .to(.trailing, constant: -25) - // To Leading Bottom With Bottom Multiplier + // To Leading Bottom with Bottom Multiplier blueView .size(width: 100, height: 100) .to(.bottom, multiplier: 0.5) .to(.leading) - // To Leading Bottom With Bottom Multiplier and Constant + // To Leading Bottom with Bottom Multiplier and Constant greenView .size(width: 100, height: 100) .to(.bottom, multiplier: 0.75, constant: 50) .to(.leading) - // To Bottom Trailing With Constant and Priority + // To Bottom Trailing with Constant and Priority orangeView .size(width: 100, height: 100) @@ -392,7 +414,7 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // To Top Leading With Less Than Or Equal Relation and Constant + // To Top Leading with Less Than Or Equal Relation and Constant pinkView .size(width: 100, height: 100) @@ -400,7 +422,7 @@ final class LayoutItemTests: XCTestCase { .to(.top, constant: 150, priority: .high) .to(.leading, constant: 50) - // To Top Trailing With Less Than Or Equal Relation and Constant + // To Top Trailing with Less Than Or Equal Relation and Constant yellowView .size(width: 100, height: 100) @@ -408,7 +430,7 @@ final class LayoutItemTests: XCTestCase { .to(.top, constant: 50, priority: .high) .to(.trailing, constant: -50) - // To Top Trailing With Greater Than Or Equal Relation and Constant + // To Top Trailing with Greater Than Or Equal Relation and Constant blueView .size(width: 100, height: 100) @@ -416,7 +438,7 @@ final class LayoutItemTests: XCTestCase { .to(.bottom, constant: -150, priority: .high) .to(.leading, constant: 50) - // To Top Trailing With Greater Than Or Equal Relation and Constant + // To Top Trailing with Greater Than Or Equal Relation and Constant greenView .size(width: 100, height: 100) @@ -431,7 +453,7 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // To Bottom Leading With Default Constant and Priority + // To Bottom Leading with Default Constant and Priority pinkView .size(width: 100, height: 100) @@ -458,14 +480,14 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // To Edges With Insets and Default Priority + // To Edges with Insets and Default Priority pinkView .toEdges(insets: NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0), priority: .high) .toEdges(insets: NSDirectionalEdgeInsets(top: 0, leading: 5, bottom: 10, trailing: 15)) - // To Edges With Insets and Priority + // To Edges with Insets and Priority yellowView .toEdges( @@ -484,14 +506,13 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // To Edges With Insets and Default Priority + // To Edges with Insets and Default Priority pinkView - .toEdges(insets: UIEdgeInsets(top: 0, left: 5, bottom: 10, right: 15), - priority: .high) + .toEdges(insets: UIEdgeInsets(top: 0, left: 5, bottom: 10, right: 15), priority: .high) .toEdges(insets: UIEdgeInsets(top: 0, left: 5, bottom: 10, right: 15)) - // To Edges With Insets and Priority + // To Edges with Insets and Priority yellowView .toEdges(insets: UIEdgeInsets(top: 0, left: 5, bottom: 10, right: 15), priority: .low) @@ -504,20 +525,20 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // To Edges Top, Leading and Trailing With Default Priority + // To Edges Top, Leading and Trailing with Default Priority pinkView .size(height: 100) .toEdges([.top, .leading, .trailing], inset: 50, priority: .high) .toEdges([.top, .leading, .trailing]) - // To Edges Bottom, Leading and Trailing With Inset + // To Edges Bottom, Leading and Trailing with Inset yellowView .size(height: 100) .toEdges([.bottom, .leading, .trailing], inset: 25) - // To Edges Leading and Trailing With Vertical Center, Inset and Priority + // To Edges Leading and Trailing with Vertical Center, Inset and Priority blueView .size(height: 100) @@ -532,7 +553,7 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // To Edges With Default Edges, Inset and Priority + // To Edges with Default Edges, Inset and Priority pinkView .toEdges([.top, .leading], inset: 50, priority: .high) @@ -544,13 +565,13 @@ final class LayoutItemTests: XCTestCase { .size(height: 100) .toEdges(canonical: [.top, .left, .right]) - // To Edges Bottom, Left and Right With Inset + // To Edges Bottom, Left and Right with Inset blueView .size(height: 100) .toEdges(canonical: [.bottom, .left, .right], inset: 25) - // To Edges Left and Right With Vertical Center, Inset and Priority + // To Edges Left and Right with Vertical Center, Inset and Priority orangeView .size(height: 100) @@ -565,7 +586,7 @@ final class LayoutItemTests: XCTestCase { assertLayout { view in view.layout { - // To Side Edges With Default Inset and Priority + // To Side Edges with Default Inset and Priority pinkView .size(height: 100) @@ -573,14 +594,14 @@ final class LayoutItemTests: XCTestCase { .toSideEdges(inset: 50, priority: .high) .toSideEdges() - // To Side Edges With Inset + // To Side Edges with Inse yellowView .size(height: 100) .to(.centerY) .toSideEdges(inset: 50) - // To Side Edges With Inset and Priority + // To Side Edges with Inset and Priority blueView .size(height: 100) @@ -595,14 +616,14 @@ final class LayoutItemTests: XCTestCase { assertLayout(devices: Device.portraitTestDevices + Device.modernLandscapeTestDevices) { view in view.layout { - // To Margins With Default Priority + // To Margins with Default Priority pinkView .toMargins(insets: NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10), priority: .high) .toMargins(insets: NSDirectionalEdgeInsets.zero) - // To Margins With Insets and Priority + // To Margins with Insets and Priority blueView .toMargins(insets: NSDirectionalEdgeInsets.zero, priority: .low) @@ -616,13 +637,13 @@ final class LayoutItemTests: XCTestCase { assertLayout(devices: Device.portraitTestDevices + Device.modernLandscapeTestDevices) { view in view.layout { - // To Margins With Default Priority + // To Margins with Default Priority pinkView .toMargins(insets: UIEdgeInsets.zero, priority: .high) .toMargins(insets: UIEdgeInsets(top: 10, left: 20, bottom: 40, right: 80)) - // To Margins With Priority + // To Margins with Priority blueView .toMargins(insets: UIEdgeInsets.zero, priority: .low) @@ -635,18 +656,18 @@ final class LayoutItemTests: XCTestCase { assertLayout(devices: Device.portraitTestDevices + Device.modernLandscapeTestDevices) { view in view.layout { - // To Margins With Default Inset and Priority + // To Margins with Default Inset and Priority pinkView .toMargins([.top, .leading, .trailing, .bottom], inset: 50, priority: .high) .toMargins([.top, .leading, .trailing, .bottom]) - // To Margins With Inset + // To Margins with Inset blueView .toMargins([.top, .leading, .trailing, .bottom], inset: 25) - // To Margins With Inset and Priority + // To Margins with Inset and Priority orangeView .toMargins([.top, .leading, .trailing, .bottom], inset: 0, priority: .low) @@ -659,27 +680,27 @@ final class LayoutItemTests: XCTestCase { assertLayout(devices: Device.portraitTestDevices + Device.modernLandscapeTestDevices) { view in view.layout { - // To Margins With Default Inset and Priority + // To Margins with Default Inset and Priority pinkView - .toMargins(canonical: [.top, .left], inset: 50, priority: .high) + .toMargins(canonical: CanonicalEdge.allCases, inset: 50, priority: .high) .toMargins() - // To Margins With Inset + // To Margins with Inset blueView .toMargins(inset: 25) - // To Margins With Inset and Priority + // To Margins with Inset and Priority orangeView .toMargins(inset: 0, priority: .low) .toMargins(inset: 50, priority: .high) - // To Margins Top Left With Inset + // To Margins Top Left with Inset yellowView - .size(CGSize(width: 50, height: 50)) + .size(width: 50, height: 50) .toMargins(canonical: [.top, .left], inset: 75) } } @@ -689,7 +710,7 @@ final class LayoutItemTests: XCTestCase { assertLayout(devices: Device.portraitTestDevices + Device.modernLandscapeTestDevices) { view in view.layout { - // To Side Margins With Default Inset and Priority + // To Side Margins with Default Inset and Priority pinkView .to(.top) @@ -697,14 +718,14 @@ final class LayoutItemTests: XCTestCase { .toSideMargins() .toSideMargins(inset: 20, priority: .high) - // To Side Margins With Inset + // To Side Margins with Inset blueView .center(.vertical) .size(height: 100) .toSideMargins(inset: 20) - // To Side Margins With Inset and Priority + // To Side Margins with Inset and Priority orangeView .to(.bottom) @@ -719,7 +740,7 @@ final class LayoutItemTests: XCTestCase { assertLayout(devices: Device.portraitTestDevices + Device.modernLandscapeTestDevices) { view in view.layout { - // To Bottom Margin Leading With Default Priority + // To Bottom Margin Leading with Default Priority pinkView .size(width: 100, height: 100) @@ -727,7 +748,7 @@ final class LayoutItemTests: XCTestCase { .toBottomMargin(minInset: 200, priority: .high) .toBottomMargin(minInset: 100) - // To Bottom Margin Trailing With Priority + // To Bottom Margin Trailing with Priority blueView .size(width: 100, height: 100) @@ -738,40 +759,18 @@ final class LayoutItemTests: XCTestCase { } } - func testCenterBetweenTopAndBottom() { - assertLayout(devices: Device.allTestDevices) { view in - view.layout( - pinkView - .size(width: 200, height: 100) - .to(.leading) - .center(between: view.safeAreaLayoutGuide.top, and: view.safeAreaLayoutGuide.bottom) - ) - } - } - - func testCenterBetweenLeadingAndTrailing() { - assertLayout(devices: Device.allTestDevices) { view in - view.layout( - pinkView - .size(width: 200, height: 100) - .to(.top) - .center(between: view.safeAreaLayoutGuide.leading, and: view.safeAreaLayoutGuide.trailing) - ) - } - } - func testToSafeAreaWithDirectionalEdgeInsetsPriority() { assertLayout(devices: Device.allTestDevices) { view in view.layout { - // To Safe Area With Insets and Default Priority + // To Safe Area with Insets and Default Priority pinkView .toSafeArea(insets: NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5), priority: .high) .toSafeArea(insets: NSDirectionalEdgeInsets(top: 0, leading: 5, bottom: 10, trailing: 15)) - // To Safe Area With Insets and Priority + // To Safe Area with Insets and Priority yellowView .toSafeArea( @@ -790,13 +789,13 @@ final class LayoutItemTests: XCTestCase { assertLayout(devices: Device.allTestDevices) { view in view.layout { - // To Safe Area With Insets and Default Priority + // To Safe Area with Insets and Default Priority pinkView .toSafeArea(insets: UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5), priority: .high) .toSafeArea(insets: UIEdgeInsets(top: 0, left: 5, bottom: 10, right: 15)) - // To Safe Area With Insets and Priority + // To Safe Area with Insets and Priority yellowView .toSafeArea(insets: UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5), priority: .low) @@ -809,13 +808,13 @@ final class LayoutItemTests: XCTestCase { assertLayout(devices: Device.allTestDevices) { view in view.layout { - // To Safe Area With Default Priority + // To Safe Area with Default Priority pinkView .toSafeArea(DirectionalEdge.allCases, inset: 50, priority: .high) .toSafeArea(DirectionalEdge.allCases) - // To Safe Area With Inset and Priority + // To Safe Area with Inset and Priority blueView .toSafeArea(DirectionalEdge.allCases, inset: 0, priority: .low) @@ -828,22 +827,22 @@ final class LayoutItemTests: XCTestCase { assertLayout(devices: Device.allTestDevices) { view in view.layout { - // To Safe Area With Default Edges, Inset and Priority + // To Safe Area with Default Edges, Inset and Priority pinkView .toSafeArea(canonical: [.top, .left], inset: 50, priority: .high) .toSafeArea() - // To Safe Area With Inset and Priority + // To Safe Area with Inset and Priority blueView .toSafeArea(inset: 0, priority: .low) .toSafeArea(inset: 50, priority: .high) - // To Safe Area Top Left Right Bottom With Inset + // To Safe Area Top Left Right Bottom with Inset orangeView - .toSafeArea(canonical: [.top, .left, .right, .bottom], inset: 75) + .toSafeArea(canonical: CanonicalEdge.allCases, inset: 75) } } } diff --git a/Tests/LayoutTests/LayoutTests.swift b/Tests/LayoutTests/LayoutTests.swift index 56691c0a..a6bc81f4 100644 --- a/Tests/LayoutTests/LayoutTests.swift +++ b/Tests/LayoutTests/LayoutTests.swift @@ -353,34 +353,34 @@ final class LayoutTests: XCTestCase { yellowView } - // Constrain View Attribute To Target Attribute of Target View With Constant, Default Relation and + // Constrain View Attribute To Target Attribute of Target View with Constant, Default Relation and // Multiplier layout.constrain(pinkView, .bottom, to: .top, of: yellowView, constant: -12) - // Constrain To View Attribute To Target Attribute of Target View With Greater Than Or Equal Relation and + // Constrain To View Attribute To Target Attribute of Target View with Greater Than Or Equal Relation and // Default Multiplier layout.constrain(pinkView, .top, to: .top, of: view, constant: 20) layout.constrain(pinkView, .top, is: .greaterThanOrEqual, to: .top, of: view, constant: 6) - // Constraint To View Attribute To Target Attribute of Target View With Less Than Or Equal Relation and + // Constraint To View Attribute To Target Attribute of Target View with Less Than Or Equal Relation and // Default Multiplier layout.constrain(yellowView, .bottom, is: .lessThanOrEqual, to: .bottom, of: view, constant: -10) layout.constrain(yellowView, .bottom, to: .bottom, of: view, constant: -20) - // Constrain View To Target Attribute of Target View With Constant, Default Attribute, Relation and + // Constrain View To Target Attribute of Target View with Constant, Default Attribute, Relation and // Multiplier layout.constrain(pinkView, to: .leading, of: view, constant: 4) - // Constrain View To Target Attribute of Target View With Default Attribute, Relation, Constant and + // Constrain View To Target Attribute of Target View with Default Attribute, Relation, Constant and // Multiplier layout.constrain(yellowView, to: .leading, of: view) - // Constrain To View Attribute With Relation, Target Attribute of Target View, Multiplier, and Default + // Constrain To View Attribute with Relation, Target Attribute of Target View, Multiplier, and Default // Constant layout.constrain(pinkView, .width, is: .equal, to: .width, of: view, multiplier: 0.75) @@ -408,7 +408,7 @@ final class LayoutTests: XCTestCase { yellowView } - // Constrain Anchor to Target Anchor With Default Relation, Constant, and Priority + // Constrain Anchor to Target Anchor with Default Relation, Constant, and Priority layout.constrain(pinkView.leading, is: .greaterThanOrEqual, @@ -417,7 +417,7 @@ final class LayoutTests: XCTestCase { priority: .high) layout.constrain(pinkView.leading, to: view.leading) - // Constrain Anchor To Target Anchor With Constant, Default Relation and Priority + // Constrain Anchor To Target Anchor with Constant, Default Relation and Priority layout.constrain(yellowView.leading, to: view.leading, constant: 20) layout.constrain(pinkView.trailing, to: view.trailing, constant: -20) @@ -439,7 +439,7 @@ final class LayoutTests: XCTestCase { priority: .high ) - // Constrain Anchor To Target Anchor With Greater Than Or Equal Relation, Constant and Priority + // Constrain Anchor To Target Anchor with Greater Than Or Equal Relation, Constant and Priority layout.constrain( pinkView.bottom, @@ -463,7 +463,7 @@ final class LayoutTests: XCTestCase { priority: .high ) - // Constrain Anchor To Target Anchor With Less Than Or Equal Relation, Constant and Priority + // Constrain Anchor To Target Anchor with Less Than Or Equal Relation, Constant and Priority layout.constrain( yellowView.bottom, @@ -519,7 +519,7 @@ final class LayoutTests: XCTestCase { .to(.bottom, constant: -10) } - // Constrain Anchor To Target Anchor With Default Relation, Multiplier, Constant and Priority + // Constrain Anchor To Target Anchor with Default Relation, Multiplier, Constant and Priority layout.constrain(pinkView.height, is: .greaterThanOrEqual, @@ -529,15 +529,15 @@ final class LayoutTests: XCTestCase { priority: .high) layout.constrain(pinkView.height, to: yellowView.height) - // Constrain Anchor To Target Anchor With Constant, Default Relation, Multiplier and Priority + // Constrain Anchor To Target Anchor with Constant, Default Relation, Multiplier and Priority layout.constrain(pinkView.width, to: view.width, constant: -150) - // Constrain Anchor To Target Anchor With Multiplier, Default Relation, Constant and Priority + // Constrain Anchor To Target Anchor with Multiplier, Default Relation, Constant and Priority layout.constrain(yellowView.width, to: view.width, multiplier: 0.33) - // Constrain Anchor to Target Anchor With Priority, Default Relation, Multiplier and Constant + // Constrain Anchor to Target Anchor with Priority, Default Relation, Multiplier and Constant layout.constrain(blueView.width, to: view.width, priority: .low) layout.constrain(blueView.width, to: yellowView.width, priority: .high) @@ -549,7 +549,7 @@ final class LayoutTests: XCTestCase { layout.constrain(greenView.height, to: yellowView.height, constant: -50, priority: .low) layout.constrain(greenView.height, to: yellowView.height, constant: 50, priority: .high) - // Constrain Anchor To Target Anchor With Less Than or Equal Relation, Default Multiplier, Constant and + // Constrain Anchor To Target Anchor with Less Than or Equal Relation, Default Multiplier, Constant and // Priority layout.constrain(greenView.width, is: .lessThanOrEqual, to: yellowView.width) @@ -579,23 +579,23 @@ final class LayoutTests: XCTestCase { .to([.trailing, .bottom], constant: -20) } - // Constrain Anchor With Constant, Default Relation and Priority + // Constrain Anchor with Constant, Default Relation and Priority layout.constrain(pinkView.height, is: .greaterThanOrEqual, to: 150, priority: .high) layout.constrain(pinkView.height, to: 100) - // Constrain Anchor With Greater Than Or Equal Relation, Constant and Default Priority + // Constrain Anchor with Greater Than Or Equal Relation, Constant and Default Priority layout.constrain(pinkView.width, is: .greaterThanOrEqual, to: 40) layout.constrain(pinkView.width, to: 20, priority: .low) layout.constrain(pinkView.width, to: 200, priority: .high) - // Constrain Anchor With Constant, Priority, and Default Relation + // Constrain Anchor with Constant, Priority, and Default Relation layout.constrain(yellowView.height, to: 25, priority: .low) layout.constrain(yellowView.height, to: 100, priority: .high) - // Constrain Anchor With Less Than Or Equal Relation, Constant and Priority + // Constrain Anchor with Less Than Or Equal Relation, Constant and Priority layout.constrain(yellowView.width, is: .lessThanOrEqual, to: 250, priority: .high) layout.constrain(yellowView.width, to: 300, priority: .low) @@ -614,16 +614,11 @@ final class LayoutTests: XCTestCase { // THEN assertLayout { view in - - let layout: Layout = view.layout(pinkView) - - // Pin View1 To View2 with Insets - - layout.constrain(pinkView, - to: view, - insets: NSDirectionalEdgeInsets(top: 40, leading: 40, bottom: 40, trailing: 40)) - - return layout + view + .layout(pinkView) + .constrain(pinkView, + to: view, + insets: NSDirectionalEdgeInsets(top: 40, leading: 40, bottom: 40, trailing: 40)) } } @@ -643,11 +638,11 @@ final class LayoutTests: XCTestCase { yellowView } - // Pin View1 To View2 With Default Insets + // Pin View1 To View2 with Default Insets layout.constrain(pinkView, to: view) - // Pin View1 To View2 With Insets + // Pin View1 To View2 with Insets layout.constrain(yellowView, to: view, @@ -681,19 +676,19 @@ final class LayoutTests: XCTestCase { assertLayout { view in view.layout { + + // Equal Width Attribute + pinkView .size(width: 50, height: 50) .to([.top, .leading]) + + // Equal Height Attribute + yellowView .to([.top, .trailing]) } - - // Equal Width Attribute - .equal(.width, [pinkView, yellowView]) - - // Equal Height Attribute - .equal(.height, [pinkView, yellowView]) } } @@ -767,7 +762,7 @@ final class LayoutTests: XCTestCase { .size(width: 50, height: 50) } - // Horizontal Views With Alignment, Default Spacing, Direction and Priority + // Horizontal Views with Alignment, Default Spacing, Direction and Priority layout.horizontal([pinkView, yellowView], spacing: 20, @@ -776,7 +771,7 @@ final class LayoutTests: XCTestCase { alignment: .centerY) layout.horizontal([pinkView, yellowView], alignment: .centerY) - // Horizontal Views With Spacing, Direction, Priority and Alignment + // Horizontal Views with Spacing, Direction, Priority and Alignment layout.horizontal( [blueView, greenView], @@ -817,7 +812,7 @@ final class LayoutTests: XCTestCase { .size(width: 100, height: 50, priority: .low) } - // Horizontal Views With Flexible View, Alignment, Default Spacing, Direction and Priority + // Horizontal Views with Flexible View, Alignment, Default Spacing, Direction and Priority layout.horizontal([pinkView, yellowView], spacing: 20, @@ -857,12 +852,12 @@ final class LayoutTests: XCTestCase { .size(width: 50, height: 50) } - // Vertical Views With Alignment, Default Spacing and Priority + // Vertical Views with Alignment, Default Spacing and Priority layout.vertical([pinkView, yellowView], spacing: 20, priority: .high, alignment: .centerX) layout.vertical([pinkView, yellowView], alignment: .centerX) - // Vertical Views With Spacing, Alignment, and Priority + // Vertical Views with Spacing, Alignment, and Priority layout.vertical([blueView, greenView], spacing: 20, priority: .low, alignment: .centerX) layout.vertical([blueView, greenView], spacing: 12, priority: .high, alignment: .centerX) @@ -890,7 +885,7 @@ final class LayoutTests: XCTestCase { .size(width: 50, height: 100, priority: .low) } - // Vertical Views With Flexible View, Alignment, Default Spacing and Priority + // Vertical Views with Flexible View, Alignment, Default Spacing and Priority layout.vertical([pinkView, yellowView], spacing: 20, priority: .high, alignment: .leading, .trailing) layout.vertical([pinkView, yellowView], alignment: .leading, .trailing) @@ -938,12 +933,12 @@ final class LayoutTests: XCTestCase { .to(.trailing) } - // Center View Between Top Anchor and Bottom Anchor With Default Priority + // Center View Between Top Anchor and Bottom Anchor with Default Priority layout.center(yellowView, between: view.top, and: view.centerY, priority: .high) layout.center(yellowView, between: view.top, and: view.bottom) - // Center View Between Top Anchor and Bottom Anchor With Priority + // Center View Between Top Anchor and Bottom Anchor with Priority layout.center(pinkView, between: yellowView.top, and: yellowView.bottom, priority: .low) layout.center(pinkView, between: view.top, and: view.bottom, priority: .high) diff --git a/Tests/LayoutTests/Support/SnapshotTesting.swift b/Tests/LayoutTests/Support/SnapshotTesting.swift index 1cf4f155..e1abc649 100644 --- a/Tests/LayoutTests/Support/SnapshotTesting.swift +++ b/Tests/LayoutTests/Support/SnapshotTesting.swift @@ -85,86 +85,6 @@ extension Device.Orientation { } } -/* - Provides configuration for iPhone 13 and iPhone 13 mini when performing tests via `pod lib lint` since - the snapshot testing library only supports CocoaPods in an older v1.9 version. - - This extension may be removed when CocoaPods support is removed from Layout. - - Reference: - https://github.com/pointfreeco/swift-snapshot-testing/blob/main/Sources/SnapshotTesting/Common/View.swift - */ -extension ViewImageConfig { - - internal static let iPhone13: ViewImageConfig = .iPhone13(.portrait) - internal static let iPhone13Mini: ViewImageConfig = .iPhone13Mini(.portrait) - - internal static func iPhone13(_ orientation: Orientation) -> ViewImageConfig { - let safeArea: UIEdgeInsets - let size: CGSize - switch orientation { - case .landscape: - safeArea = UIEdgeInsets(top: 0, left: 47, bottom: 21, right: 47) - size = CGSize(width: 844, height: 390) - case .portrait: - safeArea = UIEdgeInsets(top: 47, left: 0, bottom: 34, right: 0) - size = CGSize(width: 390, height: 844) - } - return ViewImageConfig(safeArea: safeArea, size: size, traits: .iPhone13(orientation)) - } - - internal static func iPhone13Mini(_ orientation: Orientation) -> ViewImageConfig { - let safeArea: UIEdgeInsets - let size: CGSize - switch orientation { - case .landscape: - safeArea = UIEdgeInsets(top: 0, left: 50, bottom: 21, right: 50) - size = CGSize(width: 812, height: 375) - case .portrait: - safeArea = UIEdgeInsets(top: 50, left: 0, bottom: 34, right: 0) - size = CGSize(width: 375, height: 812) - } - return ViewImageConfig(safeArea: safeArea, size: size, traits: .iPhone13(orientation)) - } -} - -/* - Provides configuration for iPhone 13 and iPhone 13 mini when performing tests via `pod lib lint` since - the snapshot testing library only supports CocoaPods in an older v1.9 version. - - This extension may be removed when CocoaPods support is removed from Layout. - - Reference: - https://github.com/pointfreeco/swift-snapshot-testing/blob/main/Sources/SnapshotTesting/Common/View.swift - */ -extension UITraitCollection { - - internal static func iPhone13(_ orientation: ViewImageConfig.Orientation) -> UITraitCollection { - let base: [UITraitCollection] = [ - UITraitCollection(forceTouchCapability: .available), - UITraitCollection(layoutDirection: .leftToRight), - UITraitCollection(preferredContentSizeCategory: .medium), - UITraitCollection(userInterfaceIdiom: .phone) - ] - switch orientation { - case .landscape: - return UITraitCollection( - traitsFrom: base + [ - UITraitCollection(horizontalSizeClass: .compact), - UITraitCollection(verticalSizeClass: .compact) - ] - ) - case .portrait: - return UITraitCollection( - traitsFrom: base + [ - UITraitCollection(horizontalSizeClass: .compact), - UITraitCollection(verticalSizeClass: .regular) - ] - ) - } - } -} - extension UIView { // swiftlint:disable:next strict_fileprivate diff --git a/Tests/LayoutTests/UIView+AutoLayoutTests.swift b/Tests/LayoutTests/UIView+AutoLayoutTests.swift index 208283e9..315c21a3 100644 --- a/Tests/LayoutTests/UIView+AutoLayoutTests.swift +++ b/Tests/LayoutTests/UIView+AutoLayoutTests.swift @@ -32,9 +32,12 @@ final class UIViewAutoLayoutTests: XCTestCase { // GIVEN - let bounds: CGRect = .init(x: 0, y: 0, width: 10, height: 20) - let view: UIView = .init() - view.bounds = bounds + let frame: CGRect = .init(x: 0, y: 0, width: 10, height: 20) + let view: UIView = .init(frame: frame) + + // THEN + + expect(view.translatesAutoresizingMaskIntoConstraints) == true // WHEN @@ -43,8 +46,8 @@ final class UIViewAutoLayoutTests: XCTestCase { // THEN expect(view.translatesAutoresizingMaskIntoConstraints) == false - expect(view.constraints.first { $0.firstAttribute == .width }?.constant) == bounds.width - expect(view.constraints.first { $0.firstAttribute == .height }?.constant) == bounds.height + expect(view.constraints.first { $0.firstAttribute == .width }?.constant) == frame.width + expect(view.constraints.first { $0.firstAttribute == .height }?.constant) == frame.height } func testConstrainingSize() { @@ -66,8 +69,11 @@ final class UIViewAutoLayoutTests: XCTestCase { // GIVEN let width: CGFloat = 10 - let view: UIView = .init() - view.bounds = .init(x: 0, y: 0, width: width, height: 0) + let view: UIView = .init(frame: CGRect(x: 0, y: 0, width: width, height: 0)) + + // THEN + + expect(view.translatesAutoresizingMaskIntoConstraints) == true // WHEN @@ -97,8 +103,11 @@ final class UIViewAutoLayoutTests: XCTestCase { // GIVEN let height: CGFloat = 20 - let view: UIView = .init() - view.bounds = .init(x: 0, y: 0, width: 0, height: height) + let view: UIView = .init(frame: CGRect(x: 0, y: 0, width: 0, height: height)) + + // THEN + + expect(view.translatesAutoresizingMaskIntoConstraints) == true // WHEN @@ -130,11 +139,20 @@ final class UIViewAutoLayoutTests: XCTestCase { let superview: UIView = .init() let view: UIView = .init() superview.addSubview(view) + + // THEN + + expect(superview.constraints).to(beEmpty()) + + // WHEN + view.constrain(to: superview) - let constraints: [NSLayoutConstraint] = superview.constraints // THEN + let constraints: [NSLayoutConstraint] = superview.constraints + + expect(superview.constraints.count) == 4 expect(constraints[0].firstAttribute) == .leading expect(constraints[0].constant) == 0 expect(constraints[1].firstAttribute) == .trailing @@ -153,7 +171,7 @@ final class UIViewAutoLayoutTests: XCTestCase { let view: UIView = .init() superview.addSubview(view) let insets: NSDirectionalEdgeInsets = .init(top: 1, leading: 2, bottom: 3, trailing: 4) - view.constrain(to: superview, directionalEdgeInsets: insets) + view.constrain(to: superview, insets: insets) let constraints: [NSLayoutConstraint] = superview.constraints // THEN @@ -175,11 +193,6 @@ final class UIViewAutoLayoutTests: XCTestCase { let superview: UIView = .init() let view: UIView = .init() superview.addSubview(view) - - // WHEN - - // Constraints To Superview Attributes With Default Relation, Multiplier and Constant - let constraints1: [NSLayoutConstraint] = view.constraints(toSuperview: [.top]) // THEN @@ -189,9 +202,7 @@ final class UIViewAutoLayoutTests: XCTestCase { expect(constraints1.first?.multiplier) == 1 expect(constraints1.first?.constant) == 0 - // WHEN - - // Constraints To Superview Attributes With Relation, Multiplier and Constant + // GIVEN let constraints2: [NSLayoutConstraint] = view.constraints( is: .greaterThanOrEqual, @@ -214,11 +225,6 @@ final class UIViewAutoLayoutTests: XCTestCase { let view: UIView = .init() let targetView: UIView = .init() - - // WHEN - - // Constraints To Attributes of TargetView With Default Relation, Multiplier and Constant - let constraints1: [NSLayoutConstraint] = view.constraints(to: [.top], of: targetView) // THEN @@ -228,9 +234,7 @@ final class UIViewAutoLayoutTests: XCTestCase { expect(constraints1.first?.multiplier) == 1 expect(constraints1.first?.constant) == 0 - // WHEN - - // Constraints To Attributes of TargetView With Relation, Multiplier and Constant + // GIVEN let constraints2: [NSLayoutConstraint] = view.constraints( is: .greaterThanOrEqual, @@ -253,11 +257,6 @@ final class UIViewAutoLayoutTests: XCTestCase { // GIVEN let view: UIView = .init() - - // WHEN - - // Width Constraint With Default Relation and Constant - let widthConstraint1: NSLayoutConstraint = view.widthConstraint() // THEN @@ -269,11 +268,6 @@ final class UIViewAutoLayoutTests: XCTestCase { let relation2: NSLayoutConstraint.Relation = .greaterThanOrEqual let width2: CGFloat = 10 - - // WHEN - - // Width Constraint With Greater Than Or Equal Relation and Constant - let widthConstraint2: NSLayoutConstraint = view.widthConstraint(is: relation2, width2) // THEN @@ -285,11 +279,6 @@ final class UIViewAutoLayoutTests: XCTestCase { let relation3: NSLayoutConstraint.Relation = .lessThanOrEqual let width3: CGFloat = 20 - - // WHEN - - // Width Constraint With Less Than Or Equal Relation and Constant - let widthConstraint3: NSLayoutConstraint = view.widthConstraint(is: relation3, width3) // THEN @@ -303,11 +292,6 @@ final class UIViewAutoLayoutTests: XCTestCase { // GIVEN let view: UIView = .init() - - // WHEN - - // Height Constraint With Default Relation and Constant - let heightConstraint1: NSLayoutConstraint = view.heightConstraint() // THEN @@ -319,11 +303,6 @@ final class UIViewAutoLayoutTests: XCTestCase { let relation2: NSLayoutConstraint.Relation = .greaterThanOrEqual let height2: CGFloat = 10 - - // WHEN - - // Height Constraint With Greater Than Or Equal Relation and Constant - let heightConstraint2: NSLayoutConstraint = view.heightConstraint(is: relation2, height2) // THEN @@ -335,11 +314,6 @@ final class UIViewAutoLayoutTests: XCTestCase { let relation3: NSLayoutConstraint.Relation = .lessThanOrEqual let height3: CGFloat = 20 - - // WHEN - - // Height Constraint With Less Than Or Equal Relation and Constant - let heightConstraint3: NSLayoutConstraint = view.heightConstraint(is: relation3, height3) // THEN @@ -353,11 +327,6 @@ final class UIViewAutoLayoutTests: XCTestCase { // GIVEN let view: UIView = .init() - - // WHEN - - // Size Constraint With Default Size - let sizeConstraints1: [NSLayoutConstraint] = view.sizeConstraints() // THEN @@ -367,9 +336,7 @@ final class UIViewAutoLayoutTests: XCTestCase { expect(sizeConstraints1[1].firstAttribute) == .height expect(sizeConstraints1[1].constant) == 0 - // WHEN - - // Size Constraint With Size + // GIVEN let sizeConstraints2: [NSLayoutConstraint] = view.sizeConstraints(.init(width: 10, height: 20)) @@ -401,6 +368,9 @@ final class UIViewAutoLayoutTests: XCTestCase { let ratio: CGFloat = 0.5 let view: UIView = .init() + + // WHEN + let constraint: NSLayoutConstraint = view.aspectConstraint(ratio) // THEN @@ -409,48 +379,21 @@ final class UIViewAutoLayoutTests: XCTestCase { expect(constraint.secondAttribute) == .height expect(constraint.relation) == .equal expect(constraint.multiplier) == ratio - } - - func testEdgeConstraints() { - - // GIVEN - - let superview: UIView = .init() - let view: UIView = .init() - superview.addSubview(view) - - // WHEN - - // Edge Constraints With Default Insets - - let constraints: [NSLayoutConstraint] = view.edgeConstraints() - - // THEN - - expect(constraints[0].firstAttribute) == .top - expect(constraints[0].constant) == 0 - expect(constraints[1].firstAttribute) == .bottom - expect(constraints[1].constant) == 0 - expect(constraints[2].firstAttribute) == .leading - expect(constraints[2].constant) == 0 - expect(constraints[3].firstAttribute) == .trailing - expect(constraints[3].constant) == 0 // GIVEN let superview2: UIView = .init() let view2: UIView = .init() - let insets: DirectionalInsets = .init(top: 0, leading: 5, bottom: 10, trailing: 15) superview2.addSubview(view2) // WHEN - // Edge Constraints With Insets - + let insets: DirectionalInsets = .init(top: 0, leading: 5, bottom: 10, trailing: 15) let constraints2: [NSLayoutConstraint] = view2.edgeConstraints(insetBy: insets) // THEN + expect(constraints2.count) == 4 expect(constraints2[0].firstAttribute) == .top expect(constraints2[0].constant) == 0 expect(constraints2[1].firstAttribute) == .bottom @@ -461,6 +404,27 @@ final class UIViewAutoLayoutTests: XCTestCase { expect(constraints2[3].constant) == -15 } + func testEdgeConstraints() { + + // GIVEN + + let superview: UIView = .init() + let view: UIView = .init() + superview.addSubview(view) + let constraints: [NSLayoutConstraint] = view.edgeConstraints() + + // THEN + + expect(constraints[0].firstAttribute) == .top + expect(constraints[0].constant) == 0 + expect(constraints[1].firstAttribute) == .bottom + expect(constraints[1].constant) == 0 + expect(constraints[2].firstAttribute) == .leading + expect(constraints[2].constant) == 0 + expect(constraints[3].firstAttribute) == .trailing + expect(constraints[3].constant) == 0 + } + func testEdgeConstraintsInsetByValue() { // GIVEN @@ -515,8 +479,6 @@ final class UIViewAutoLayoutTests: XCTestCase { // WHEN - // Center Constraints With Default Offset - let constraints1: [NSLayoutConstraint] = view.centerConstraints() // THEN @@ -532,8 +494,6 @@ final class UIViewAutoLayoutTests: XCTestCase { // WHEN - // Center Constraints With Offset - let constraints2: [NSLayoutConstraint] = view.centerConstraints(offsetBy: offset) // THEN