426 lines
16 KiB
Swift
426 lines
16 KiB
Swift
//
|
|
// UITableView+RxTests.swift
|
|
// Rx
|
|
//
|
|
// Created by Krunoslav Zaher on 4/8/16.
|
|
// Copyright © 2016 Krunoslav Zaher. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import RxSwift
|
|
import RxCocoa
|
|
import XCTest
|
|
|
|
class UITableViewTests : RxTest {
|
|
func testTableView_DelegateEventCompletesOnDealloc() {
|
|
let createView: () -> UITableView = { UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1)) }
|
|
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_itemSelected }
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_itemDeselected }
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_itemAccessoryButtonTapped }
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_modelSelected(Int.self) }
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_itemDeleted }
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_itemMoved }
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_itemInserted }
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_modelSelected(Int.self) }
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_modelDeselected(Int.self) }
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_willDisplayCell }
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_didEndDisplayingCell }
|
|
}
|
|
|
|
func testTableView_itemSelected() {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
|
|
var resultIndexPath: IndexPath? = nil
|
|
|
|
let subscription = tableView.rx_itemSelected
|
|
.subscribe(onNext: { indexPath in
|
|
resultIndexPath = indexPath
|
|
})
|
|
|
|
let testRow = IndexPath(row: 1, section: 0)
|
|
tableView.delegate!.tableView!(tableView, didSelectRowAt: testRow)
|
|
|
|
XCTAssertEqual(resultIndexPath, testRow)
|
|
subscription.dispose()
|
|
}
|
|
|
|
func testTableView_itemDeselected() {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
|
|
var resultIndexPath: IndexPath? = nil
|
|
|
|
let subscription = tableView.rx_itemDeselected
|
|
.subscribe(onNext: { indexPath in
|
|
resultIndexPath = indexPath
|
|
})
|
|
|
|
let testRow = IndexPath(row: 1, section: 0)
|
|
tableView.delegate!.tableView!(tableView, didDeselectRowAt: testRow)
|
|
|
|
XCTAssertEqual(resultIndexPath, testRow)
|
|
subscription.dispose()
|
|
}
|
|
|
|
func testTableView_itemAccessoryButtonTapped() {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
|
|
var resultIndexPath: IndexPath? = nil
|
|
|
|
let subscription = tableView.rx_itemAccessoryButtonTapped
|
|
.subscribe(onNext: { indexPath in
|
|
resultIndexPath = indexPath
|
|
})
|
|
|
|
let testRow = IndexPath(row: 1, section: 0)
|
|
tableView.delegate!.tableView!(tableView, accessoryButtonTappedForRowWith: testRow)
|
|
|
|
XCTAssertEqual(resultIndexPath, testRow)
|
|
subscription.dispose()
|
|
}
|
|
|
|
func testTableView_itemDeleted() {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
|
|
var resultIndexPath: IndexPath? = nil
|
|
|
|
let subscription = tableView.rx_itemDeleted
|
|
.subscribe(onNext: { indexPath in
|
|
resultIndexPath = indexPath
|
|
})
|
|
|
|
let testRow = IndexPath(row: 1, section: 0)
|
|
tableView.dataSource!.tableView!(tableView, commit: .delete, forRowAt: testRow)
|
|
|
|
XCTAssertEqual(resultIndexPath, testRow)
|
|
subscription.dispose()
|
|
}
|
|
|
|
func testTableView_itemInserted() {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
|
|
var resultIndexPath: IndexPath? = nil
|
|
|
|
let subscription = tableView.rx_itemInserted
|
|
.subscribe(onNext: { indexPath in
|
|
resultIndexPath = indexPath
|
|
})
|
|
|
|
let testRow = IndexPath(row: 1, section: 0)
|
|
tableView.dataSource!.tableView!(tableView, commit: .insert, forRowAt: testRow)
|
|
|
|
XCTAssertEqual(resultIndexPath, testRow)
|
|
subscription.dispose()
|
|
}
|
|
|
|
func testTableView_willDisplayCell() {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
|
|
var resultIndexPath: IndexPath? = nil
|
|
var resultCell: UITableViewCell? = nil
|
|
|
|
let subscription = tableView.rx_willDisplayCell
|
|
.subscribe(onNext: { (cell, indexPath) in
|
|
resultIndexPath = indexPath
|
|
resultCell = cell
|
|
})
|
|
|
|
let testRow = IndexPath(row: 1, section: 0)
|
|
let testCell = UITableViewCell()
|
|
tableView.delegate!.tableView!(tableView, willDisplay: testCell, forRowAt: testRow)
|
|
|
|
XCTAssertEqual(resultIndexPath, testRow)
|
|
XCTAssertEqual(resultCell, testCell)
|
|
subscription.dispose()
|
|
}
|
|
|
|
func testTableView_didEndDisplayingCell() {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
|
|
var resultIndexPath: IndexPath? = nil
|
|
var resultCell: UITableViewCell? = nil
|
|
|
|
let subscription = tableView.rx_didEndDisplayingCell
|
|
.subscribe(onNext: { (cell, indexPath) in
|
|
resultIndexPath = indexPath
|
|
resultCell = cell
|
|
})
|
|
|
|
let testRow = IndexPath(row: 1, section: 0)
|
|
let testCell = UITableViewCell()
|
|
tableView.delegate!.tableView!(tableView, didEndDisplaying: testCell, forRowAt: testRow)
|
|
|
|
XCTAssertEqual(resultIndexPath, testRow)
|
|
XCTAssertEqual(resultCell, testCell)
|
|
subscription.dispose()
|
|
}
|
|
|
|
func testTableView_itemMoved() {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
|
|
var resultIndexPath: IndexPath? = nil
|
|
var resultIndexPath2: IndexPath? = nil
|
|
|
|
let subscription = tableView.rx_itemMoved
|
|
.subscribe(onNext: { (indexPath, indexPath2) in
|
|
resultIndexPath = indexPath
|
|
resultIndexPath2 = indexPath2
|
|
})
|
|
|
|
let testRow = IndexPath(row: 1, section: 0)
|
|
let testRow2 = IndexPath(row: 1, section: 0)
|
|
tableView.dataSource!.tableView!(tableView, moveRowAt: testRow, to: testRow2)
|
|
|
|
XCTAssertEqual(resultIndexPath, testRow)
|
|
XCTAssertEqual(resultIndexPath2, testRow2)
|
|
subscription.dispose()
|
|
}
|
|
|
|
func testTableView_DelegateEventCompletesOnDealloc1() {
|
|
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
|
|
|
let createView: () -> (UITableView, Disposable) = {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
let dataSourceSubscription = items.bindTo(tableView.rx_items) { (tv, index: Int, item: Int) -> UITableViewCell in
|
|
return UITableViewCell(style: .default, reuseIdentifier: "Identity")
|
|
}
|
|
|
|
return (tableView, dataSourceSubscription)
|
|
}
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_modelSelected(Int.self) }
|
|
}
|
|
|
|
func testTableView_DelegateEventCompletesOnDealloc2() {
|
|
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
|
|
|
let createView: () -> (UITableView, Disposable) = {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
tableView.register(NSClassFromString("UITableViewCell"), forCellReuseIdentifier: "a")
|
|
let dataSourceSubscription = items.bindTo(tableView.rx_items(cellIdentifier: "a")) { (index: Int, item: Int, cell) in
|
|
|
|
}
|
|
|
|
return (tableView, dataSourceSubscription)
|
|
}
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_modelSelected(Int.self) }
|
|
}
|
|
|
|
func testTableView_DelegateEventCompletesOnDealloc2_cellType() {
|
|
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
|
|
|
let createView: () -> (UITableView, Disposable) = {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
tableView.register(NSClassFromString("UITableViewCell"), forCellReuseIdentifier: "a")
|
|
let dataSourceSubscription = items.bindTo(tableView.rx_items(cellIdentifier: "a", cellType: UITableViewCell.self)) { (index: Int, item: Int, cell) in
|
|
|
|
}
|
|
|
|
return (tableView, dataSourceSubscription)
|
|
}
|
|
ensureEventDeallocated(createView) { (view: UITableView) in view.rx_modelSelected(Int.self) }
|
|
}
|
|
|
|
func testTableView_ModelSelected_rx_itemsWithCellFactory() {
|
|
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
|
|
|
let createView: () -> (UITableView, Disposable) = {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
let dataSourceSubscription = items.bindTo(tableView.rx_items) { (tv, index: Int, item: Int) -> UITableViewCell in
|
|
return UITableViewCell(style: .default, reuseIdentifier: "Identity")
|
|
}
|
|
|
|
return (tableView, dataSourceSubscription)
|
|
}
|
|
|
|
let (tableView, dataSourceSubscription) = createView()
|
|
|
|
var selectedItem: Int? = nil
|
|
|
|
let s = tableView.rx_modelSelected(Int.self)
|
|
.subscribe(onNext: { item in
|
|
selectedItem = item
|
|
})
|
|
|
|
tableView.delegate!.tableView!(tableView, didSelectRowAt: IndexPath(row: 1, section: 0))
|
|
|
|
XCTAssertEqual(selectedItem, 2)
|
|
|
|
dataSourceSubscription.dispose()
|
|
s.dispose()
|
|
}
|
|
|
|
func testTableView_ModelSelected_itemsWithCellIdentifier() {
|
|
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
|
|
|
let createView: () -> (UITableView, Disposable) = {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
tableView.register(NSClassFromString("UITableViewCell"), forCellReuseIdentifier: "a")
|
|
let dataSourceSubscription = items.bindTo(tableView.rx_items(cellIdentifier: "a")) { (index: Int, item: Int, cell) in
|
|
|
|
}
|
|
|
|
return (tableView, dataSourceSubscription)
|
|
}
|
|
|
|
let (tableView, dataSourceSubscription) = createView()
|
|
|
|
var selectedItem: Int? = nil
|
|
|
|
let s = tableView.rx_modelSelected(Int.self)
|
|
.subscribe(onNext: { item in
|
|
selectedItem = item
|
|
})
|
|
|
|
tableView.delegate!.tableView!(tableView, didSelectRowAt: IndexPath(row: 1, section: 0))
|
|
|
|
XCTAssertEqual(selectedItem, 2)
|
|
|
|
dataSourceSubscription.dispose()
|
|
s.dispose()
|
|
}
|
|
|
|
func testTableView_ModelDeselected_rx_itemsWithCellFactory() {
|
|
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
|
|
|
let createView: () -> (UITableView, Disposable) = {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
let dataSourceSubscription = items.bindTo(tableView.rx_items) { (tv, index: Int, item: Int) -> UITableViewCell in
|
|
return UITableViewCell(style: .default, reuseIdentifier: "Identity")
|
|
}
|
|
|
|
return (tableView, dataSourceSubscription)
|
|
}
|
|
|
|
let (tableView, dataSourceSubscription) = createView()
|
|
|
|
var selectedItem: Int? = nil
|
|
|
|
let s = tableView.rx_modelDeselected(Int.self)
|
|
.subscribe(onNext: { item in
|
|
selectedItem = item
|
|
})
|
|
|
|
tableView.delegate!.tableView!(tableView, didDeselectRowAt: IndexPath(row: 1, section: 0))
|
|
|
|
XCTAssertEqual(selectedItem, 2)
|
|
|
|
dataSourceSubscription.dispose()
|
|
s.dispose()
|
|
}
|
|
|
|
func testTableView_ModelDeselected_itemsWithCellIdentifier() {
|
|
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
|
|
|
let createView: () -> (UITableView, Disposable) = {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
tableView.register(NSClassFromString("UITableViewCell"), forCellReuseIdentifier: "a")
|
|
let dataSourceSubscription = items.bindTo(tableView.rx_items(cellIdentifier: "a")) { (index: Int, item: Int, cell) in
|
|
|
|
}
|
|
|
|
return (tableView, dataSourceSubscription)
|
|
}
|
|
|
|
let (tableView, dataSourceSubscription) = createView()
|
|
|
|
var selectedItem: Int? = nil
|
|
|
|
let s = tableView.rx_modelDeselected(Int.self)
|
|
.subscribe(onNext: { item in
|
|
selectedItem = item
|
|
})
|
|
|
|
tableView.delegate!.tableView!(tableView, didDeselectRowAt: IndexPath(row: 1, section: 0))
|
|
|
|
XCTAssertEqual(selectedItem, 2)
|
|
|
|
dataSourceSubscription.dispose()
|
|
s.dispose()
|
|
}
|
|
|
|
func testTableView_modelAtIndexPath_normal() {
|
|
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
|
|
|
let createView: () -> (UITableView, Disposable) = {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
tableView.register(NSClassFromString("UITableViewCell"), forCellReuseIdentifier: "a")
|
|
let dataSource = SectionedViewDataSourceMock()
|
|
let dataSourceSubscription = items.bindTo(tableView.rx_items(dataSource: dataSource))
|
|
|
|
return (tableView, dataSourceSubscription)
|
|
}
|
|
|
|
let (tableView, dataSourceSubscription) = createView()
|
|
|
|
let model: Int = try! tableView.rx_modelAtIndexPath(IndexPath(item: 1, section: 0))
|
|
|
|
XCTAssertEqual(model, 2)
|
|
|
|
dataSourceSubscription.dispose()
|
|
}
|
|
}
|
|
|
|
extension UITableViewTests {
|
|
func testDataSourceIsBeingRetainedUntilDispose() {
|
|
|
|
var dataSourceDeallocated = false
|
|
|
|
var dataSourceSubscription: Disposable!
|
|
autoreleasepool {
|
|
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
|
let dataSource = SectionedViewDataSourceMock()
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
dataSourceSubscription = items.bindTo(tableView.rx_items(dataSource: dataSource))
|
|
|
|
_ = dataSource.rx_deallocated.subscribe(onNext: { _ in
|
|
dataSourceDeallocated = true
|
|
})
|
|
}
|
|
|
|
XCTAssert(dataSourceDeallocated == false)
|
|
dataSourceSubscription.dispose()
|
|
XCTAssert(dataSourceDeallocated == true)
|
|
}
|
|
|
|
func testDataSourceIsBeingRetainedUntilTableViewDealloc() {
|
|
|
|
var dataSourceDeallocated = false
|
|
|
|
autoreleasepool {
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "a")
|
|
|
|
let items: Observable<[Int]> = Observable.just([1, 2, 3])
|
|
let dataSource = SectionedViewDataSourceMock()
|
|
_ = items.bindTo(tableView.rx_items(dataSource: dataSource))
|
|
|
|
_ = dataSource.rx_deallocated.subscribe(onNext: { _ in
|
|
dataSourceDeallocated = true
|
|
})
|
|
|
|
XCTAssert(dataSourceDeallocated == false)
|
|
}
|
|
XCTAssert(dataSourceDeallocated == true)
|
|
}
|
|
|
|
func testSetDataSourceUsesWeakReference() {
|
|
|
|
var dataSourceDeallocated = false
|
|
|
|
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
|
|
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "a")
|
|
|
|
autoreleasepool {
|
|
let dataSource = SectionedViewDataSourceMock()
|
|
_ = tableView.rx_setDataSource(dataSource)
|
|
|
|
_ = dataSource.rx_deallocated.subscribe(onNext: { _ in
|
|
dataSourceDeallocated = true
|
|
})
|
|
|
|
XCTAssert(dataSourceDeallocated == false)
|
|
}
|
|
XCTAssert(dataSourceDeallocated == true)
|
|
}
|
|
}
|