Checking and unchecking items

The last thing we need to make sure in ItemListDataProvider is that we can check and uncheck items and that they can then change sections. Unfortunately, like in the last test, we need to invoke the responsible data source method directly in the test. We would like to have some kind of high-level method to call to simulate the user tapping the Check and Uncheck buttons, such as in numberOfRows(inSection:), but UIKit does not provide these. We will see how to use UI tests to simulate the taps of the user later in the book. Here, we will use the data source method to do this. Add the following test to ItemListDataProviderTests:

func test_CheckingAnItem_ChecksItInTheItemManager() { 
  sut.itemManager?.add(ToDoItem(title: "Foo")) 
   

  tableView.dataSource?.tableView?(tableView, 
                                   commit: .delete, 
                                   forRowAt: IndexPath(row: 0, 
                                                       section: 0)) 
  
 
  XCTAssertEqual(sut.itemManager?.toDoCount, 0) 
  XCTAssertEqual(sut.itemManager?.doneCount, 1) 
  XCTAssertEqual(tableView.numberOfRows(inSection: 0), 0) 
  XCTAssertEqual(tableView.numberOfRows(inSection: 1), 1) 
} 

This test fails because we have not implemented tableView(_:commit:forRowAt:) yet. Add the following code to ItemListDataProvider:

func tableView(_ tableView: UITableView, 
               commit editingStyle: UITableViewCellEditingStyle, 
               forRowAt indexPath: IndexPath) { 

   
  itemManager?.checkItem(at: indexPath.row) 
  tableView.reloadData() 
} 

Run the tests. All the tests pass and there is nothing to refactor.

Next, we need to write a test for the unchecking of a to-do item. Add the following test to ItemListDataProviderTests:

func test_UncheckingAnItem_UnchecksItInTheItemManager() { 
   

  sut.itemManager?.add(ToDoItem(title: "First")) 
  sut.itemManager?.checkItem(at: 0) 
  tableView.reloadData() 
  tableView.dataSource?.tableView?(tableView, 
                                   commit: .delete, 
                                   forRowAt: IndexPath(row: 0, 
                                                       section: 1)) 
   

  XCTAssertEqual(sut.itemManager?.toDoCount, 1) 
  XCTAssertEqual(sut.itemManager?.doneCount, 0) 
  XCTAssertEqual(tableView.numberOfRows(inSection: 0), 1) 
  XCTAssertEqual(tableView.numberOfRows(inSection: 1), 0) 
} 

This test results in a crash because the code in tableView(_:commit:forRowAt:) tries to remove an item for the unchecked items, but the corresponding array in the item manager is already empty. Replace the implementation of tableView(_:commit:forRowAt:) with the following code:

func tableView(_ tableView: UITableView, 
               commit editingStyle: UITableViewCellEditingStyle, 
               forRowAt indexPath: IndexPath) { 
   

  guard let itemManager = itemManager else { fatalError() } 
  guard let section = Section(rawValue: indexPath.section) else 
  { 
    fatalError() 
  } 
   

  switch section { 
  case .toDo: 
    itemManager.checkItem(at: indexPath.row) 
  case .done: 
    itemManager.uncheckItem(at: indexPath.row) 
  } 
  tableView.reloadData() 
} 

This implementation code results in a message from the static analyzer saying 'ItemManager' has no member 'uncheckItemAtIndex'. It looks like we forgot to add it in the previous chapter so, let's add it now. Add the following method to ItemManager:

func uncheckItem(at index: Int) { 
  let item = doneItems.remove(at: index) 
  toDoItems.append(item) 
} 

Run the tests. All the tests pass and there is nothing to refactor.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.191.134