diff --git a/README.md b/README.md
index c31752bb4..968bfd595 100644
--- a/README.md
+++ b/README.md
@@ -46,6 +46,7 @@ The following documents are available:
| CloudEvents SDK Requirements | [v0.3](https://github.com/cloudevents/spec/blob/v0.3/SDK.md) | [master](https://github.com/cloudevents/spec/blob/master/SDK.md) |
| Documented Extensions | - | [master](https://github.com/cloudevents/spec/blob/master/documented-extensions.md) |
| Primer | [v0.3](https://github.com/cloudevents/spec/blob/v0.3/primer.md) | [master](https://github.com/cloudevents/spec/blob/master/primer.md) |
+| Edge cases for SDK testing | - | [master](https://github.com/cloudevents/spec/blob/master/testcases/README.md) |
| Proprietary Specifications | - | [master](https://github.com/cloudevents/spec/blob/master/proprietary-specs.md) |
If you are new to CloudEvents, it is recommended that you start by reading the
diff --git a/testcases/README.md b/testcases/README.md
new file mode 100644
index 000000000..7ed8fa1bb
--- /dev/null
+++ b/testcases/README.md
@@ -0,0 +1,40 @@
+# Test cases for CloudEvents encoding
+
+These cases provide a set of "difficult" or edge-case encodings of valid
+CloudEvents, for use in testing various CloudEvents implementations. The cases
+cover transformation between a [canonical JSON object](../json-format.md) and a
+transport-specific output. Test cases are organized by common prefix with the
+following suffixes denoting different transports:
+
+| Suffix | Encoding |
+| ----------- | ------------------------------------------------------- |
+| `json` | [JSON event](../json-format.md) |
+| `http` | [HTTP binary request](../http-transport-binding.md) |
+| `http-json` | [HTTP structured request](../http-transport-binding.md) |
+| `mqtt` | [MQTT binary publish](../mqtt-transport-binding.md) |
+| `mqtt-json` | [MQTT structured publish](../mqtt-transport-binding.md) |
+| `amqp` | [AMQP message](../amqp-transport-binding.md) |
+
+If multiple files exist with the same input prefix, they all represent the same
+CloudEvent rendered across the different transports. For example, given the
+files:
+
+- `unicode-input.json`
+- `unicode-input.http`
+- `unicode-input.mqtt`
+- `binary-date.json`
+- `binary-date.amqp`
+
+These form two sets of tests: the `unicode-input` case is defined for JSON,
+HTTP, and MQTT, and the `binary-date` case is defined for JSON and AMQP.
+
+Test cases which describe particularly unexpected formats should include
+comments in the JSON document using Javascript comment format (`//` or
+`/* .. */`).
+
+
diff --git a/testcases/contenttype.http b/testcases/contenttype.http
new file mode 100644
index 000000000..1e5df9558
--- /dev/null
+++ b/testcases/contenttype.http
@@ -0,0 +1,10 @@
+POST / HTTP/1.1
+Host: handler.example.com
+Content-Type: application/xml
+Content-Length: 24
+ce-specversion: 0.4-wip
+ce-id: 123
+ce-source: https://cloudevents.io/contenttype
+ce-type: io.cloudevents.contenttype-test
+
+
\ No newline at end of file
diff --git a/testcases/contenttype.json b/testcases/contenttype.json
new file mode 100644
index 000000000..af86c63e9
--- /dev/null
+++ b/testcases/contenttype.json
@@ -0,0 +1,11 @@
+{
+ "specversion": "0.4-wip",
+ "id": "123",
+
+ "source": "https://cloudevents.io/contenttype",
+ "type": "io.cloudevents.contenttype-test",
+
+ "datacontenttype": "application/xml",
+
+ "data_base64": "PG11Y2ggd293PSJ4bWwiLz4=" //
+}
diff --git a/testcases/contenttype.mqtt b/testcases/contenttype.mqtt
new file mode 100644
index 000000000..458329893
--- /dev/null
+++ b/testcases/contenttype.mqtt
@@ -0,0 +1,11 @@
+------------------ PUBLISH ---------------
+Topic Name: mytopic
+Content Type: application/xml
+--------------- User Properties ----------
+specversion: 0.4-wip
+id: 123
+source: https://cloudevents.io/contenttype
+type: io.cloudevents.contenttype-test
+------------------ payload ---------------
+
+------------------------------------------
\ No newline at end of file
diff --git a/testcases/unicode-strings.http b/testcases/unicode-strings.http
new file mode 100644
index 000000000..7f879a483
--- /dev/null
+++ b/testcases/unicode-strings.http
@@ -0,0 +1,9 @@
+POST / HTTP/1.1
+Host: handler.example.com
+Content-Length: 0
+ce-specversion: 0.4-wip
+ce-id: %22%F0%9F%98%89%03%3c.is%2BFine%E7%81%AB%22
+ce-source: https://cloudevents.io/unicode-strings
+ce-type: " -.-. . "
+ce-subject: " "
+
diff --git a/testcases/unicode-strings.http-json b/testcases/unicode-strings.http-json
new file mode 100644
index 000000000..0710250d5
--- /dev/null
+++ b/testcases/unicode-strings.http-json
@@ -0,0 +1,12 @@
+POST / HTTP/1.1
+Host: handler.example.com
+Content-Length: 279
+Content-Type: applications/cloudevents+json; charset=utf-8
+
+{
+ "specversion": "0.4-wip",
+ "id": "\"😉\u033c.is+Fine火\u0022", // \u22\u1F609\u033c\u2e\u69\u73\u2b\u46\u69\u6e\u65\u706b\u22
+ "source": "https://cloudevents.io/unicode-strings",
+ "type": " -.-. . "
+ "subject": " "
+}
\ No newline at end of file
diff --git a/testcases/unicode-strings.json b/testcases/unicode-strings.json
new file mode 100644
index 000000000..e65414182
--- /dev/null
+++ b/testcases/unicode-strings.json
@@ -0,0 +1,16 @@
+{
+ "specversion": "0.4-wip",
+ // "Printable" might or might not include " ", but probably includes
+ // characters that produce at least some visible output
+ // Go defines this as:
+ // > Such characters include letters, marks, numbers, punctuation, symbols,
+ // > and spaces, from categories L, M, N, P, S, Zs.
+ // https://golang.org/pkg/unicode/#IsGraphic
+ "id": "\"😉\u033c.is+Fine火\u0022", // \u22\u1F609\u033c\u2e\u69\u73\u2b\u46\u69\u6e\u65\u706b\u22
+
+ "source": "https://cloudevents.io/unicode-strings"
+ "type": " -.-. . "
+
+ // OPTIONAL field
+ "subject": " "
+}
diff --git a/testcases/unicode-strings.mqtt b/testcases/unicode-strings.mqtt
new file mode 100644
index 000000000..c3ee673b6
--- /dev/null
+++ b/testcases/unicode-strings.mqtt
@@ -0,0 +1,11 @@
+------------------ PUBLISH ---------------
+Topic Name: mytopic
+Content Type:
+--------------- User Properties ----------
+specversion:0.4-wip
+id:"😉̼.is+Fine火"
+source:https://cloudevents.io/unicode-strings
+type: -.-. .
+subject:
+------------------ payload ---------------
+------------------------------------------
\ No newline at end of file
diff --git a/testcases/urls.http b/testcases/urls.http
new file mode 100644
index 000000000..6b1cf961b
--- /dev/null
+++ b/testcases/urls.http
@@ -0,0 +1,9 @@
+oPOST / HTTP/1.1
+Host: handler.example.com
+Content-Length: 0
+ce-specversion: 0.4-wip
+ce-id: 123
+ce-source: /
+ce-type: io.cloudevetns.url-test
+ce-schemaurl: %252f%252fanonymous%40example.com/a&b;?x'=%252f//#%//
+
diff --git a/testcases/urls.json b/testcases/urls.json
new file mode 100644
index 000000000..0b6cf0965
--- /dev/null
+++ b/testcases/urls.json
@@ -0,0 +1,16 @@
+{
+ "specversion": "0.4-wip",
+
+ "id": "123",
+
+ // Source is a URI-reference, https://tools.ietf.org/html/rfc3986#appendix-A
+ "source": "/", // relative-ref -> relative-part -> path-absolute
+ "type": "io.cloudevents.url-test",
+
+ // URI-reference: https://tools.ietf.org/html/rfc3986#appendix-A
+ // Verify that % decoding is performed correctly (no % decoding in
+ // JSON, HTTP headers should be decoded). This is a 'path-noscheme'
+ // which percent-decodes to a different valid URI:
+ // relative-ref -> relative-part -> '"//" authority path-abempty'.
+ "schemaurl": "%2f%2fanonymous@example.com/a&b;?x'=%2f//#//"
+}
\ No newline at end of file