From e70c1f9fa392af9e7dab71f899080dff75311d85 Mon Sep 17 00:00:00 2001 From: Kazuhiro Hayashi <kazuhiro.hayashi.49@gmail.com> Date: Sun, 20 Jan 2019 18:52:35 +0900 Subject: [PATCH 1/3] added guard statement when numberOfItem is zero --- PagingKit/PagingMenuView.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PagingKit/PagingMenuView.swift b/PagingKit/PagingMenuView.swift index e59ef1a..cb7c3f0 100644 --- a/PagingKit/PagingMenuView.swift +++ b/PagingKit/PagingMenuView.swift @@ -346,6 +346,10 @@ open class PagingMenuView: UIScrollView { /// - Parameter index: An index that identifies a item by its index. /// - Returns: A rectangle defining the area in which the table view draws the row or right edge rect if index is over the number of items. open func rectForItem(at index: Int) -> CGRect { + guard 0 < widths.count else { + return CGRect(x: 0, y: 0, width: 0, height: bounds.height) + } + guard index < widths.count else { let rightEdge = widths.reduce(CGFloat(0)) { (sum, width) in sum + width } let mostRightWidth = widths[widths.endIndex - 1] From 4696cdc85bf3a35a4119200e15203f869bbc949e Mon Sep 17 00:00:00 2001 From: Kazuhiro Hayashi <kazuhiro.hayashi.49@gmail.com> Date: Sun, 20 Jan 2019 19:09:50 +0900 Subject: [PATCH 2/3] added a boundary tests --- PagingKit/PagingMenuView.swift | 6 ++ PagingKitTests/PagingMenuViewTests.swift | 74 +++++++++++++++++++++++- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/PagingKit/PagingMenuView.swift b/PagingKit/PagingMenuView.swift index cb7c3f0..f882cb3 100644 --- a/PagingKit/PagingMenuView.swift +++ b/PagingKit/PagingMenuView.swift @@ -356,6 +356,12 @@ open class PagingMenuView: UIScrollView { return CGRect(x: rightEdge, y: 0, width: mostRightWidth, height: bounds.height) } + guard 0 <= index else { + let leftEdge = -widths[0] + let mostLeftWidth = widths[0] + return CGRect(x: leftEdge, y: 0, width: mostLeftWidth, height: bounds.height) + } + var x = (0..<index).reduce(0) { (sum, idx) in return sum + widths[idx] } diff --git a/PagingKitTests/PagingMenuViewTests.swift b/PagingKitTests/PagingMenuViewTests.swift index 4e0a19c..c0e88f2 100644 --- a/PagingKitTests/PagingMenuViewTests.swift +++ b/PagingKitTests/PagingMenuViewTests.swift @@ -115,9 +115,77 @@ class PagingMenuViewTests: XCTestCase { pagingMenuView?.dataSource = dataSource pagingMenuView?.reloadData() - let rect = pagingMenuView?.rectForItem(at: 3) - XCTAssertEqual(rect, - CGRect(x: 300, y: 0, width: 100, height: 44), "get correct rect") + + do { + let rect = pagingMenuView?.rectForItem(at: -2) + XCTAssertEqual(rect, + CGRect(x: -100, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + let rect = pagingMenuView?.rectForItem(at: -1) + XCTAssertEqual(rect, + CGRect(x: -100, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + // first index + let rect = pagingMenuView?.rectForItem(at: 0) + XCTAssertEqual(rect, + CGRect(x: 0, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + let rect = pagingMenuView?.rectForItem(at: 3) + XCTAssertEqual(rect, + CGRect(x: 300, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + // last index + let rect = pagingMenuView?.rectForItem(at: 19) + XCTAssertEqual(rect, + CGRect(x: 1900, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + let rect = pagingMenuView?.rectForItem(at: 20) + XCTAssertEqual(rect, + CGRect(x: 2000, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + let rect = pagingMenuView?.rectForItem(at: 21) + XCTAssertEqual(rect, + CGRect(x: 2000, y: 0, width: 100, height: 44), "get correct rect") + } + } + + func testRectForItemWhenDataSourceHasNoElement() { + let dataSource = MenuViewDataSourceSpy() + dataSource.widthForItem = 100 + dataSource.registerNib(to: pagingMenuView) + dataSource.data = [] + pagingMenuView?.dataSource = dataSource + pagingMenuView?.reloadData() + + do { + let rect = pagingMenuView?.rectForItem(at: -1) + XCTAssertEqual(rect, + CGRect(x: 0, y: 0, width: 0, height: 44), "get correct rect") + } + + do { + let rect = pagingMenuView?.rectForItem(at: 0) + XCTAssertEqual(rect, + CGRect(x: 0, y: 0, width: 0, height: 44), "get correct rect") + } + + do { + let rect = pagingMenuView?.rectForItem(at: 1) + XCTAssertEqual(rect, + CGRect(x: 0, y: 0, width: 0, height: 44), "get correct rect") + } } func testRectForItemToEdgeCase() { From 9511e46251b5b75029151ea14963b0cc446d7027 Mon Sep 17 00:00:00 2001 From: Kazuhiro Hayashi <kazuhiro.hayashi.49@gmail.com> Date: Sun, 20 Jan 2019 19:24:39 +0900 Subject: [PATCH 3/3] added boundary test for spacing --- PagingKit/PagingMenuView.swift | 11 ++--- PagingKitTests/PagingMenuViewTests.swift | 55 ++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/PagingKit/PagingMenuView.swift b/PagingKit/PagingMenuView.swift index f882cb3..8abaed6 100644 --- a/PagingKit/PagingMenuView.swift +++ b/PagingKit/PagingMenuView.swift @@ -217,6 +217,11 @@ open class PagingMenuView: UIScrollView { /// space setting between cells open var cellSpacing: CGFloat = 0 + /// total space between cells + open var totalSpacing: CGFloat { + return cellSpacing * numberOfCellSpacing + } + /// The object that acts as the data source of the paging menu view. open weak var dataSource: PagingMenuViewDataSource? @@ -351,7 +356,7 @@ open class PagingMenuView: UIScrollView { } guard index < widths.count else { - let rightEdge = widths.reduce(CGFloat(0)) { (sum, width) in sum + width } + let rightEdge = widths.reduce(CGFloat(0)) { (sum, width) in sum + width } + totalSpacing let mostRightWidth = widths[widths.endIndex - 1] return CGRect(x: rightEdge, y: 0, width: mostRightWidth, height: bounds.height) } @@ -525,10 +530,6 @@ open class PagingMenuView: UIScrollView { return max(CGFloat(numberOfItem - 1), 0) } - private var totalSpacing: CGFloat { - return cellSpacing * numberOfCellSpacing - } - private func recenterIfNeeded() { let currentOffset = contentOffset let contentWidth = contentSize.width diff --git a/PagingKitTests/PagingMenuViewTests.swift b/PagingKitTests/PagingMenuViewTests.swift index c0e88f2..b7027d3 100644 --- a/PagingKitTests/PagingMenuViewTests.swift +++ b/PagingKitTests/PagingMenuViewTests.swift @@ -161,6 +161,61 @@ class PagingMenuViewTests: XCTestCase { } } + func testRectForItemWithSpacing() { + let dataSource = MenuViewDataSourceSpy() + dataSource.widthForItem = 100 + dataSource.registerNib(to: pagingMenuView) + dataSource.data = Array(repeating: "foo", count: 20) + pagingMenuView?.dataSource = dataSource + pagingMenuView?.cellSpacing = 10 + pagingMenuView?.reloadData() + + + do { + let rect = pagingMenuView?.rectForItem(at: -2) + XCTAssertEqual(rect, + CGRect(x: -100, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + let rect = pagingMenuView?.rectForItem(at: -1) + XCTAssertEqual(rect, + CGRect(x: -100, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + // first index + let rect = pagingMenuView?.rectForItem(at: 0) + XCTAssertEqual(rect, + CGRect(x: 0, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + let rect = pagingMenuView?.rectForItem(at: 3) + XCTAssertEqual(rect, + CGRect(x: 330, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + // last index + let rect = pagingMenuView?.rectForItem(at: 19) + XCTAssertEqual(rect, + CGRect(x: 2090, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + let rect = pagingMenuView?.rectForItem(at: 20) + XCTAssertEqual(rect, + CGRect(x: 2190, y: 0, width: 100, height: 44), "get correct rect") + } + + do { + let rect = pagingMenuView?.rectForItem(at: 21) + XCTAssertEqual(rect, + CGRect(x: 2190, y: 0, width: 100, height: 44), "get correct rect") + } + } + func testRectForItemWhenDataSourceHasNoElement() { let dataSource = MenuViewDataSourceSpy() dataSource.widthForItem = 100