 @testable import DynamoDB
 
 class DynamoDBTests: XCTestCase {
-    static var allTests : [(String, (DynamoDBTests) -> () throws -> Void)] {
-        return [
-            ("testGetObject", testGetObject),
-        ]
+
+    struct TestData {
+        
+        var tableName: String
+        
+        init(_ testName: String) {
+            let testName = testName.lowercased().filter { return $0.isLetter }
+            self.tableName = "\(testName)-tablename"
+        }
     }
 
-    var client: DynamoDB {
-        return DynamoDB(
+    var client = DynamoDB(
             accessKeyId: "key",
             secretAccessKey: "secret",
             region: .apnortheast1,
             endpoint: "http://localhost:4569"
         )
-    }
 
-    var tableName: String {
-        return "aws-sdk-swift-test-table"
-    }
 
-    func prepare() throws {
+    func setUp(_ testData: TestData) throws {
         let createTableInput = DynamoDB.CreateTableInput(
             attributeDefinitions: [
                 DynamoDB.AttributeDefinition(attributeName: "hashKey", attributeType: .s),

                DynamoDB.KeySchemaElement(attributeName: "rangeKey", keyType: .range)
            ],
            provisionedThroughput: DynamoDB.ProvisionedThroughput(readCapacityUnits: 10, writeCapacityUnits: 10),
            tableName: tableName
        )
        _ = try client.createTable(createTableInput).wait()


                "hashKey": DynamoDB.AttributeValue(s: "hello"),
                "rangeKey": DynamoDB.AttributeValue(s: "world")
            ],
            tableName: testData.tableName
        )
        _ = try client.putItem(putItemInput).wait()
    }

    func tearDown(_ testData: TestData) throws {
        let input = DynamoDB.DeleteTableInput(tableName: testData.tableName)
        _ = try client.deleteTable(input).wait()
    }

    func testGetObject() {
        attempt {
            
            let testData = TestData(#function)
            try setUp(testData)

            let input = DynamoDB.GetItemInput(
                key: [
                    "hashKey": DynamoDB.AttributeValue(s: "hello"),
                    "rangeKey": DynamoDB.AttributeValue(s: "world")
                ],
                tableName: testData.tableName
            )

            let output = try client.getItem(input).wait()
            XCTAssertEqual(output.item?["hashKey"]?.s, "hello")
            XCTAssertEqual(output.item?["rangeKey"]?.s, "world")
            
            try tearDown(testData)
        }
    }

    static var allTests : [(String, (DynamoDBTests) -> () throws -> Void)] {
        return [
            ("testGetObject", testGetObject),
        ]
    }
}
