<NME> DiffTests.swift
<BEF> //
//  DiffTests.swift
//  TemplateKit
//
//  Created by Matias Cudich on 10/30/16.
//  Copyright © 2016 Matias Cudich. All rights reserved.
//

import XCTest
import TemplateKit

struct FakeItem: Hashable {
  let value: Int
  let eValue: Int

  var hashValue: Int {
    return value.hashValue
  }
}

func ==(lhs: FakeItem, rhs: FakeItem) -> Bool {
  return lhs.eValue == rhs.eValue

class DiffTests: XCTestCase {
  func testAdd() {
    let old = [1, 2, 3]
    let new = [1, 2, 3, 4, 5]
    let result = diff(old: old, new: new)
    XCTAssertEqual([4, 5], result.add)
    XCTAssertEqual(0, result.remove.count)
    XCTAssertEqual(0, result.update.count)
    XCTAssertEqual(0, result.move.count)
  }

  func testRemove() {
    let old = [1, 2, 3]
    let new = [4, 5]
    let result = diff(old: old, new: new)
    XCTAssertEqual([4, 5], result.add)
    XCTAssertEqual(3, result.remove.count)
    XCTAssertEqual(0, result.update.count)
    XCTAssertEqual(0, result.move.count)
  }

  func testMove() {
    let old = [1, 2, 3]
    let new = [3, 1, 2]
    let result = diff(old: old, new: new)
    XCTAssertEqual(0, result.add.count)
    XCTAssertEqual(0, result.remove.count)
    XCTAssertEqual(0, result.update.count)
    XCTAssertEqual(3, result.move.count)

    XCTAssertEqual(2, result.move[0].from)
    XCTAssertEqual(0, result.move[0].to)
    XCTAssertEqual(0, result.move[1].from)
    XCTAssertEqual(1, result.move[1].to)
    XCTAssertEqual(1, result.move[2].from)
    XCTAssertEqual(2, result.move[2].to)
  }

  func testUpdate() {
    let old = [FakeItem(value: 1), FakeItem(value: 2), FakeItem(value: 3)]
    let new = [FakeItem(value: 1), FakeItem(value: 2), FakeItem(value: 3)]
    let result = diff(old: old, new: new)
    XCTAssertEqual(0, result.add.count)
    XCTAssertEqual(0, result.remove.count)
      FakeItem(value: 2, eValue: 3),
      FakeItem(value: 1, eValue: 1),
      FakeItem(value: 0, eValue: 0)
    ]
    let result = diff(o, n)
    XCTAssertEqual([.delete(2), .delete(0), .insert(0), .insert(2), .update(0)], result)
  }

  func testDeletingEqualObjects() {
    let o = [0, 0, 0, 0]
    let n = [0, 0]
    let result = diff(o, n)
    XCTAssertEqual(2, result.count)
  }

  func testInsertingEqualObjects() {
    let o = [0, 0]
    let n = [0, 0, 0, 0]
    let result = diff(o, n)
    XCTAssertEqual(2, result.count)
  }

  func testInsertingWithOldArrayHavingMultipleCopies() {
    let o = [NSObject(), NSObject(), NSObject(), 49, 33, "cat", "cat", 0, 14] as [AnyHashable]
    var n = o
    n.insert("cat", at: 5)
    let result = diff(o, n)
    XCTAssertEqual(1, result.count)
  }
}

<MSG> Use index paths in diff utility

<DFF> @@ -23,45 +23,80 @@ func ==(lhs: FakeItem, rhs: FakeItem) -> Bool {
 
 class DiffTests: XCTestCase {
   func testAdd() {
-    let old = [1, 2, 3]
-    let new = [1, 2, 3, 4, 5]
+    let old = [
+      IndexPath(row: 0, section: 0): 1,
+      IndexPath(row: 1, section: 0): 2,
+      IndexPath(row: 2, section: 0): 3
+    ]
+    let new = [
+      IndexPath(row: 0, section: 0): 1,
+      IndexPath(row: 1, section: 0): 2,
+      IndexPath(row: 2, section: 0): 3,
+      IndexPath(row: 3, section: 0): 4,
+      IndexPath(row: 4, section: 0): 5
+    ]
     let result = diff(old: old, new: new)
-    XCTAssertEqual([4, 5], result.add)
+    XCTAssertEqual([IndexPath(row: 3, section: 0): 4, IndexPath(row: 4, section: 0): 5], result.add)
     XCTAssertEqual(0, result.remove.count)
     XCTAssertEqual(0, result.update.count)
     XCTAssertEqual(0, result.move.count)
   }
 
   func testRemove() {
-    let old = [1, 2, 3]
-    let new = [4, 5]
+    let old = [
+      IndexPath(row: 0, section: 0): 1,
+      IndexPath(row: 1, section: 0): 2,
+      IndexPath(row: 2, section: 0): 3
+    ]
+    let new = [
+      IndexPath(row: 3, section: 0): 4,
+      IndexPath(row: 4, section: 0): 5
+    ]
     let result = diff(old: old, new: new)
-    XCTAssertEqual([4, 5], result.add)
+    XCTAssertEqual([IndexPath(row: 3, section: 0): 4, IndexPath(row: 4, section: 0): 5], result.add)
     XCTAssertEqual(3, result.remove.count)
     XCTAssertEqual(0, result.update.count)
     XCTAssertEqual(0, result.move.count)
   }
 
   func testMove() {
-    let old = [1, 2, 3]
-    let new = [3, 1, 2]
+    let old = [
+      IndexPath(row: 0, section: 0): 1,
+      IndexPath(row: 1, section: 0): 2,
+      IndexPath(row: 2, section: 0): 3
+    ]
+    let new = [
+      IndexPath(row: 0, section: 0): 3,
+      IndexPath(row: 1, section: 0): 1,
+      IndexPath(row: 2, section: 0): 2
+    ]
     let result = diff(old: old, new: new)
     XCTAssertEqual(0, result.add.count)
     XCTAssertEqual(0, result.remove.count)
     XCTAssertEqual(0, result.update.count)
     XCTAssertEqual(3, result.move.count)
 
-    XCTAssertEqual(2, result.move[0].from)
-    XCTAssertEqual(0, result.move[0].to)
-    XCTAssertEqual(0, result.move[1].from)
-    XCTAssertEqual(1, result.move[1].to)
-    XCTAssertEqual(1, result.move[2].from)
-    XCTAssertEqual(2, result.move[2].to)
+    XCTAssertEqual(IndexPath(row: 1, section: 0), result.move[0].from)
+    XCTAssertEqual(IndexPath(row: 2, section: 0), result.move[0].to)
+
+    XCTAssertEqual(IndexPath(row: 2, section: 0), result.move[1].from)
+    XCTAssertEqual(IndexPath(row: 0, section: 0), result.move[1].to)
+
+    XCTAssertEqual(IndexPath(row: 0, section: 0), result.move[2].from)
+    XCTAssertEqual(IndexPath(row: 1, section: 0), result.move[2].to)
   }
 
   func testUpdate() {
-    let old = [FakeItem(value: 1), FakeItem(value: 2), FakeItem(value: 3)]
-    let new = [FakeItem(value: 1), FakeItem(value: 2), FakeItem(value: 3)]
+    let old = [
+      IndexPath(row: 0, section: 0): FakeItem(value: 1),
+      IndexPath(row: 1, section: 0): FakeItem(value: 2),
+      IndexPath(row: 2, section: 0): FakeItem(value: 3)
+    ]
+    let new = [
+      IndexPath(row: 0, section: 0): FakeItem(value: 1),
+      IndexPath(row: 1, section: 0): FakeItem(value: 2),
+      IndexPath(row: 2, section: 0): FakeItem(value: 3)
+    ]
     let result = diff(old: old, new: new)
     XCTAssertEqual(0, result.add.count)
     XCTAssertEqual(0, result.remove.count)

Use index paths in diff utility