Identity v3 Projects Delete (#166)

diff --git a/acceptance/openstack/identity/v3/identity.go b/acceptance/openstack/identity/v3/identity.go
index 5bed8a4..f7ea48f 100644
--- a/acceptance/openstack/identity/v3/identity.go
+++ b/acceptance/openstack/identity/v3/identity.go
@@ -38,6 +38,18 @@
 	return project, nil
 }
 
+// DeleteProject will delete a project by ID. A fatal error will occur if
+// the project ID failed to be deleted. This works best when using it as
+// a deferred function.
+func DeleteProject(t *testing.T, client *gophercloud.ServiceClient, projectID string) {
+	err := projects.Delete(client, projectID).ExtractErr()
+	if err != nil {
+		t.Fatalf("Unable to delete project %s: %v", projectID, err)
+	}
+
+	t.Logf("Deleted project: %s", projectID)
+}
+
 // PrintEndpoint will print an endpoint and all of its attributes.
 func PrintEndpoint(t *testing.T, endpoint *endpoints.Endpoint) {
 	t.Logf("ID: %s", endpoint.ID)
diff --git a/acceptance/openstack/identity/v3/projects_test.go b/acceptance/openstack/identity/v3/projects_test.go
index 4b2e539..8c1c28a 100644
--- a/acceptance/openstack/identity/v3/projects_test.go
+++ b/acceptance/openstack/identity/v3/projects_test.go
@@ -70,6 +70,7 @@
 	if err != nil {
 		t.Fatalf("Unable to create project: %v", err)
 	}
+	defer DeleteProject(t, client, project.ID)
 
 	PrintProject(t, project)
 }
diff --git a/openstack/identity/v3/projects/requests.go b/openstack/identity/v3/projects/requests.go
index 07b9371..5f64211 100644
--- a/openstack/identity/v3/projects/requests.go
+++ b/openstack/identity/v3/projects/requests.go
@@ -126,3 +126,9 @@
 	_, r.Err = client.Post(createURL(client), &b, &r.Body, nil)
 	return
 }
+
+// Delete deletes a project.
+func Delete(client *gophercloud.ServiceClient, projectID string) (r DeleteResult) {
+	_, r.Err = client.Delete(deleteURL(client, projectID), nil)
+	return
+}
diff --git a/openstack/identity/v3/projects/results.go b/openstack/identity/v3/projects/results.go
index c828ff8..5a29657 100644
--- a/openstack/identity/v3/projects/results.go
+++ b/openstack/identity/v3/projects/results.go
@@ -19,6 +19,11 @@
 	projectResult
 }
 
+// DeleteResult temporarily contains the response from the Delete call.
+type DeleteResult struct {
+	gophercloud.ErrResult
+}
+
 // Project is a base unit of ownership.
 type Project struct {
 	// IsDomain indicates whether the project is a domain.
diff --git a/openstack/identity/v3/projects/testing/fixtures.go b/openstack/identity/v3/projects/testing/fixtures.go
index 0c839b8..96a4e41 100644
--- a/openstack/identity/v3/projects/testing/fixtures.go
+++ b/openstack/identity/v3/projects/testing/fixtures.go
@@ -130,3 +130,14 @@
 		fmt.Fprintf(w, GetOutput)
 	})
 }
+
+// HandleDeleteProjectSuccessfully creates an HTTP handler at `/projects` on the
+// test handler mux that tests project deletion.
+func HandleDeleteProjectSuccessfully(t *testing.T) {
+	th.Mux.HandleFunc("/projects/1234", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "DELETE")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+
+		w.WriteHeader(http.StatusNoContent)
+	})
+}
diff --git a/openstack/identity/v3/projects/testing/requests_test.go b/openstack/identity/v3/projects/testing/requests_test.go
index daed4eb..2b2e27c 100644
--- a/openstack/identity/v3/projects/testing/requests_test.go
+++ b/openstack/identity/v3/projects/testing/requests_test.go
@@ -53,3 +53,12 @@
 	th.AssertNoErr(t, err)
 	th.CheckDeepEquals(t, RedTeam, *actual)
 }
+
+func TestDeleteProject(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleDeleteProjectSuccessfully(t)
+
+	res := projects.Delete(client.ServiceClient(), "1234")
+	th.AssertNoErr(t, res.Err)
+}
diff --git a/openstack/identity/v3/projects/urls.go b/openstack/identity/v3/projects/urls.go
index 7be9dc2..c9f0d58 100644
--- a/openstack/identity/v3/projects/urls.go
+++ b/openstack/identity/v3/projects/urls.go
@@ -13,3 +13,7 @@
 func createURL(client *gophercloud.ServiceClient) string {
 	return client.ServiceURL("projects")
 }
+
+func deleteURL(client *gophercloud.ServiceClient, projectID string) string {
+	return client.ServiceURL("projects", projectID)
+}