Explicitly throw JsonException for unparseable input + some tests

Change-Id: I36f456a05111f5d90a7d471a3927497c792faf79
diff --git a/elemental/src/elemental/json/impl/JsonTokenizer.java b/elemental/src/elemental/json/impl/JsonTokenizer.java
index 1620607..b6cfbd5 100644
--- a/elemental/src/elemental/json/impl/JsonTokenizer.java
+++ b/elemental/src/elemental/json/impl/JsonTokenizer.java
@@ -110,6 +110,8 @@
         case '\r':
         case '\n':
           throw new JsonException("");
+        case INVALID_CHAR:
+          throw new JsonException("Invalid string: closing " + startChar + " is not found");
         case '\\':
           c = next();
           switch (c) {
diff --git a/elemental/tests/elemental/json/JsonUtilTest.java b/elemental/tests/elemental/json/JsonUtilTest.java
index 1dbaa88..ac887a5 100755
--- a/elemental/tests/elemental/json/JsonUtilTest.java
+++ b/elemental/tests/elemental/json/JsonUtilTest.java
@@ -124,6 +124,72 @@
     }
   }
 
+  public void testUnclosedString() {
+    try {
+      JsonUtil.parse("\"a");
+      fail("Expected JsonException to be thrown");
+    } catch (JsonException je) {
+      // Expected
+    }
+  }
+
+  public void testUnclosedEmptyString() {
+    try {
+      JsonUtil.parse("\"");
+      fail("Expected JsonException to be thrown");
+    } catch (JsonException je) {
+      // Expected
+    }
+  }
+
+  public void testUnclosedArray() {
+    try {
+      JsonUtil.parse("[1");
+      fail("Expected JsonException to be thrown");
+    } catch (JsonException je) {
+      // Expected
+    }
+  }
+
+  public void testUnclosedEmptyArray() {
+    try {
+      JsonUtil.parse("[");
+      fail("Expected JsonException to be thrown");
+    } catch (JsonException je) {
+      // Expected
+    }
+  }
+
+  public void testUnclosedObject() {
+    try {
+      JsonUtil.parse("{'a");
+      fail("Expected JsonException to be thrown");
+    } catch (JsonException je) {
+      // Expected
+    }
+    try {
+      JsonUtil.parse("{'a'");
+      fail("Expected JsonException to be thrown");
+    } catch (JsonException je) {
+      // Expected
+    }
+    try {
+      JsonUtil.parse("{'a':");
+      fail("Expected JsonException to be thrown");
+    } catch (JsonException je) {
+      // Expected
+    }
+  }
+
+  public void testUnclosedEmptyObject() {
+    try {
+      JsonUtil.parse("{");
+      fail("Expected JsonException to be thrown");
+    } catch (JsonException je) {
+      // Expected
+    }
+  }
+
   public void testLegalParse() {
     JsonValue obj = JsonUtil.parse(
         "{ \"a\":1, \"b\":\"hello\", \"c\": true,"