Skip to content

Commit

Permalink
Support additional layout options in ListAppearance. Update tests to …
Browse files Browse the repository at this point in the history
…utilize snapshot tests.
  • Loading branch information
kyleve committed Jun 15, 2020
1 parent 221d2f4 commit 79b39f3
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 85 deletions.
17 changes: 15 additions & 2 deletions Internal Pods/Snapshot/Sources/Snapshot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public struct Snapshot<Iteration:SnapshotIteration>
internal typealias OnFail = (_ message : String, _ file : StaticString, _ line : UInt) -> ()
internal var onFail : OnFail = XCTFail

public init(iterations: [Iteration] , input : Iteration.RenderingFormat)
{
self.init(iterations: iterations) { _ in input }
}

public init(iterations : [Iteration], test : @escaping Test)
{
let hasIterations = iterations.isEmpty == false
Expand Down Expand Up @@ -133,8 +138,16 @@ public protocol SnapshotOutputFormat

public struct SnapshotOutputInfo : Equatable
{
var directoryName : String
var fileExtension : String
public var directoryName : String
public var fileExtension : String

public init(
directoryName : String,
fileExtension : String
) {
self.directoryName = directoryName
self.fileExtension = fileExtension
}
}


Expand Down
8 changes: 4 additions & 4 deletions Internal Pods/Snapshot/Sources/ViewHierarchySnapshot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
import UIKit


public struct ViewHierarchySnapshot : SnapshotOutputFormat
public struct ViewHierarchySnapshot<ViewType:UIView> : SnapshotOutputFormat
{
// MARK: SnapshotOutputFormat

public typealias RenderingFormat = UIView
public typealias RenderingFormat = ViewType

public static func snapshotData(with renderingFormat : UIView) throws -> Data
public static func snapshotData(with renderingFormat : ViewType) throws -> Data
{
let hierarchy = renderingFormat.textHierarchy
let string = hierarchy.stringValue
Expand All @@ -29,7 +29,7 @@ public struct ViewHierarchySnapshot : SnapshotOutputFormat
)
}

public static func validate(render view: UIView, existingData : Data) throws
public static func validate(render view: ViewType, existingData : Data) throws
{
let textHierarchy = try ViewHierarchySnapshot.snapshotData(with: view)

Expand Down
8 changes: 4 additions & 4 deletions Internal Pods/Snapshot/Sources/ViewImageSnapshot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
import UIKit


public struct ViewImageSnapshot : SnapshotOutputFormat
public struct ViewImageSnapshot<ViewType:UIView> : SnapshotOutputFormat
{
// MARK: SnapshotOutputFormat

public typealias RenderingFormat = UIView
public typealias RenderingFormat = ViewType

public static func snapshotData(with renderingFormat : UIView) throws -> Data
public static func snapshotData(with renderingFormat : ViewType) throws -> Data
{
return renderingFormat.toImage.pngData()!
}
Expand All @@ -26,7 +26,7 @@ public struct ViewImageSnapshot : SnapshotOutputFormat
)
}

public static func validate(render newView : UIView, existingData: Data) throws
public static func validate(render newView : ViewType, existingData: Data) throws
{
let existing = try ViewImageSnapshot.image(with: existingData)
let new = newView.toImage
Expand Down
12 changes: 6 additions & 6 deletions Internal Pods/Snapshot/Sources/ViewIterations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation


public struct ViewIteration : SnapshotIteration
public struct ViewIteration<ViewType:UIView> : SnapshotIteration
{
public init(name: String)
{
Expand All @@ -17,18 +17,18 @@ public struct ViewIteration : SnapshotIteration

// MARK: SnapshotIteration

public typealias RenderingFormat = UIView
public typealias RenderingFormat = ViewType

public var name : String

public func prepare(render : UIView) -> UIView
public func prepare(render : ViewType) -> ViewType
{
return render
}
}


public struct SizedViewIteration : SnapshotIteration
public struct SizedViewIteration<ViewType:UIView> : SnapshotIteration
{
public let size : CGSize

Expand All @@ -39,13 +39,13 @@ public struct SizedViewIteration : SnapshotIteration

// MARK: SnapshotIteration

public typealias RenderingFormat = UIView
public typealias RenderingFormat = ViewType

public var name : String {
return "\(self.size.width) x \(self.size.height)"
}

public func prepare(render : UIView) -> UIView
public func prepare(render : ViewType) -> ViewType
{
render.frame.origin = .zero
render.frame.size = self.size
Expand Down
190 changes: 161 additions & 29 deletions Listable/Sources/Layout/List/DefaultListLayout.swift

Large diffs are not rendered by default.

Binary file not shown.
10 changes: 10 additions & 0 deletions Listable/Sources/Layout/ListLayout/ListLayoutAttributes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,13 @@ public struct ListLayoutAttributes : Equatable {
var frame : CGRect
}
}


extension ListLayoutAttributes {
var stringRepresentation : String {
var output = ""
dump(self, to: &output)

return output
}
}
35 changes: 35 additions & 0 deletions Listable/Tests/Layout/LayoutAttributesSnapshot.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// LayoutAttributesSnapshot.swift
// Listable
//
// Created by Kyle Van Essen on 6/11/20.
//

import Foundation
import Snapshot
@testable import Listable


struct LayoutAttributesSnapshot : SnapshotOutputFormat
{
typealias RenderingFormat = ListView

static func snapshotData(with renderingFormat: ListView) throws -> Data {
renderingFormat.layout.layout.content.layoutAttributes.stringRepresentation.data(using: .utf8)!
}

static var outputInfo: SnapshotOutputInfo {
SnapshotOutputInfo(
directoryName: "ListAttributes",
fileExtension: "txt"
)
}

static func validate(render: ListView, existingData: Data) throws {
let new = try Self.snapshotData(with: render)

if new != existingData {
throw SnapshotValidationError.notMatching
}
}
}
83 changes: 44 additions & 39 deletions Listable/Tests/Layout/List/DefaultListLayoutTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import XCTest
import Snapshot

@testable import Listable

Expand Down Expand Up @@ -70,8 +71,6 @@ class ListAppearance_LayoutTests : XCTestCase

class DefaultListLayoutTests : XCTestCase
{
// Note: This test is temporary to allow for further refactoring of the layout system. Will be replaced.

func test_layout_vertical()
{
let listView = ListView(frame: CGRect(origin: .zero, size: CGSize(width: 200.0, height: 700.0)))
Expand All @@ -80,59 +79,65 @@ class DefaultListLayoutTests : XCTestCase
listView.setContent { list in

list.appearance.direction = .vertical
list.layoutType = .list

list.appearance.list.layout = .init(
padding: UIEdgeInsets(top: 5.0, left: 10.0, bottom: 20.0, right: 15.0),
width: .noConstraint,
headerToFirstSectionSpacing: 10.0,
interSectionSpacingWithNoFooter: 15.0,
interSectionSpacingWithFooter: 20.0,
sectionHeaderBottomSpacing: 10.0,
itemSpacing: 5.0,
itemToSectionFooterSpacing: 10.0,
lastSectionToFooterSpacing: 20.0
)

list.content.header = HeaderFooter(TestingHeaderFooterContent(color: .blue), sizing: .fixed(height: 50.0))
list.content.footer = HeaderFooter(TestingHeaderFooterContent(color: .blue), sizing: .fixed(height: 70.0))

list += Section(identifier: "first") { section in
section.layout = Section.Layout(customInterSectionSpacing: 88)
section.layout = Section.Layout(customInterSectionSpacing: 30)

section.header = HeaderFooter(TestingHeaderFooterContent(color: .green), sizing: .fixed(height: 55.0))
section.footer = HeaderFooter(TestingHeaderFooterContent(color: .green), sizing: .fixed(height: 45.0))
section.header = HeaderFooter(TestingHeaderFooterContent(color: .green), sizing: .fixed(height: 30.0))
section.footer = HeaderFooter(TestingHeaderFooterContent(color: .green), sizing: .fixed(height: 40.0))

section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.1)), sizing: .fixed(height: 20.0))
section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.2)), sizing: .fixed(height: 20.0))
section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.3)), sizing: .fixed(height: 20.0))
}

list += Section(identifier: "second") { section in
section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.1)), sizing: .fixed(height: 40.0))
section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.2)), sizing: .fixed(height: 60.0))
section.header = HeaderFooter(TestingHeaderFooterContent(color: .green), sizing: .fixed(height: 30.0))
section.footer = HeaderFooter(TestingHeaderFooterContent(color: .green), sizing: .fixed(height: 40.0))

section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.1)), sizing: .fixed(height: 30.0))
section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.2)), sizing: .fixed(height: 40.0))
}

list += Section(identifier: "third") { section in
section.header = HeaderFooter(TestingHeaderFooterContent(color: .green), sizing: .fixed(height: 30.0))

section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.1)), sizing: .fixed(height: 10.0))
section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.2)), sizing: .fixed(height: 20.0))
}

list += Section(identifier: "fourth") { section in
section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.1)), sizing: .fixed(height: 10.0))
section += Item(TestingItemContent(color: .init(white: 0.0, alpha: 0.2)), sizing: .fixed(height: 20.0))
}
}

let layout = DefaultListLayout(delegate: listView.delegate, appearance: listView.appearance, behavior: listView.behavior, in: listView.collectionView)
_ = layout.layout(delegate: listView.delegate, in: listView.collectionView)
listView.collectionView.layoutIfNeeded()

let attributes = layout.content.layoutAttributes
let contentSize = listView.layout.layout.content.contentSize

let expectedAttributes = ListLayoutAttributes(
contentSize: CGSize(width: 200.0, height: 428.0),
header: .init(frame: CGRect(x: 0.0, y: 0.0, width: 200.0, height: 50.0)),
footer: .init(frame: CGRect(x: 0.0, y: 358.0, width: 200.0, height: 70.0)),
overscrollFooter: nil,
sections: [
.init(
frame: CGRect(x: 0.0, y: 50.0, width: 200.0, height: 120.0),
header: .init(frame: CGRect(x: 0.0, y: 50.0, width: 200.0, height: 55.0)),
footer: .init(frame: CGRect(x: 0.0, y: 125.0, width: 200.0, height: 45.0)),
items: [
.init(frame: CGRect(x: 0.0, y: 105.0, width: 200.0, height: 20.0))
]
),

.init(
frame: CGRect(x: 0.0, y: 258.0, width: 200.0, height: 100.0),
header: nil,
footer: nil,
items: [
.init(frame: CGRect(x: 0.0, y: 258.0, width: 200.0, height: 40.0)),
.init(frame: CGRect(x: 0.0, y: 298.0, width: 200.0, height: 60.0)),
]
),

]
)

XCTAssertEqual(attributes, expectedAttributes)
listView.frame.size.height = contentSize.height

let snapshot = Snapshot(iterations: [SizedViewIteration<ListView>(size: contentSize)], input: listView)

snapshot.test(output: ViewImageSnapshot.self)
snapshot.test(output: LayoutAttributesSnapshot.self)
}

// Note: This test is temporary to allow for further refactoring of the layout system. Will be replaced.
Expand Down
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: ede5b0b1b0dfe04b49195609ea6bccb6b577e01f

COCOAPODS: 1.8.4
COCOAPODS: 1.9.3

0 comments on commit 79b39f3

Please sign in to comment.