                        | a  b  0 |
  [x' y' 1] = [x y 1] × | c  d  0 |
                        | tx ty 1 |
+
+ y
+ ^
+ |
+ |
+ 0ーーーー> x
  */
+
+enum Transform {
+    case translate(x: CGFloat, y: CGFloat)
+    case rotate(angle: CGFloat)
+}
 
 class ProcessingViewDelegateTransformSpy: ProcessingViewDelegate {
     private let exception: XCTestExpectation
     private let view: ProcessingView
-    private let x: CGFloat
-    private let y: CGFloat
+    private let transform: Transform
     private(set) var context: CGContext?
 
-    init(exception: XCTestExpectation, view: ProcessingView, x: CGFloat, y: CGFloat) {
+    init(exception: XCTestExpectation, view: ProcessingView, transform: Transform) {
         self.exception = exception
         self.view = view
-        self.x = x
-        self.y = y
+        self.transform = transform
     }
 
     func setup() {
-        self.view.translate(x, y)
+        switch transform {
+        case .translate(let x, let y):
+            self.view.translate(x, y)
+        case .rotate(let angle):
+            self.view.rotate(angle)
+        }
         self.record(UIGraphicsGetCurrentContext())
         exception.fulfill()
     }

    }

    func testRotate() {

    }

    func check(testCases: [UInt: TestCase]) {
        _ = testCases.map { (line, testCase) in
            let view = ProcessingView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))

            let translateDelegateSpy = ProcessingViewDelegateTransformSpy(
                exception: expectation(description: testCase.description),
                view: view,
                x: testCase.transform.x,
                y: testCase.transform.y
            )

            view.delegate = translateDelegateSpy
            waitForExpectations(timeout: 100)

            let actual = translateDelegateSpy.context?.ctm
            let expected = testCase.expect
            XCTAssertEqual(actual, expected, String(line))
        }
    }

    struct TestCase {
        let description: String
        let transform: (x: CGFloat, y: CGFloat)
        let expect: CGAffineTransform

        init(
            description: String,
            transform: (x: CGFloat, y: CGFloat),
            expect: CGAffineTransform
            ) {
            self.description = description

        let testCases: [UInt: TestCase] = [
            #line: TestCase(
                description: "Move 100pt to the right",
                transform: .translate(x: 100.0, y: 0.0),
                expect: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 100.0, ty: 0.0)
            ),
            #line: TestCase(
                description: "Move 50pt to the bottom",
                transform: .translate(x: 0.0, y: 50.0),
                expect: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: -50.0)
            ),
            #line: TestCase(
                description: "Move 40pt to the left, 20pt to the top",
                transform: .translate(x: -40.0, y: -20.0),
                expect: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: -40.0, ty: 20.0)
            ),
        ]

