@Test
public void json() {

  // Empty string or JSON values are not allowed.
  assertFalse(new UriTokenizer("").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("1").next(TokenKind.jsonArrayOrObject));
  // object with values
  assertTrue(new UriTokenizer("{}").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("{\"name\":0}").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("{\"name\":true}").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("{\"name\":false}").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("{\"name\":null}").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("{\"name\":\"value\"}").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("{\"name\":\"value\",\"name2\":null}").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("{\"name\"}").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("{\"name\":}").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("{0}").next(TokenKind.jsonArrayOrObject));
  // array with values
  assertTrue(new UriTokenizer("[]").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("[1]").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("[true]").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("[false]").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("[null]").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("[\"value\"]").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("[\"\"]").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("[\"\\b\\t\\f\\r\\nn\\/\\\\x\\uFE4Fu\\\"\"]").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("[1,2.0,3.4E5]").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("[\"value\",null]").next(TokenKind.jsonArrayOrObject));
  // nesting
  assertTrue(new UriTokenizer("[{\"name\":\"value\"},{\"name\":\"value2\"}]").next(TokenKind.jsonArrayOrObject));
  assertTrue(new UriTokenizer("{\"name\":{\"name2\":\"value\"}}").next(TokenKind.jsonArrayOrObject));
  // unbalanced opening and closing
  assertFalse(new UriTokenizer("{").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("}").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("{]").next(TokenKind.jsonArrayOrObject));
  // missing values
  assertFalse(new UriTokenizer("[1,]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[,1]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[1,,2]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[1,x]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[+\"x\"]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("{\"name\":1,}").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("{,\"name\":1}").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("{\"name\":1,,\"name2\":2}").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("{\"name\":1,x}").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("{\"name\":1,\"name2\"}").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("{\"name\":1,\"name2\":}").next(TokenKind.jsonArrayOrObject));
  // wrong JSON strings
  assertFalse(new UriTokenizer("[\"a").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[\"a]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[\"a\"\"]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[\"\\x\"]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[\"\\ux\"]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[\"\\u1\"]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[\"\\u12x\"]").next(TokenKind.jsonArrayOrObject));
  assertFalse(new UriTokenizer("[\"\\u123x\"]").next(TokenKind.jsonArrayOrObject));
  wrongToken(TokenKind.jsonArrayOrObject, "[{\"name\":+123.456},null]", '\\');
}