blob: dfc12c575039501cce6f7dd070a2701a21b2c892 [file] [log] [blame]
package com.fasterxml.jackson.core.read;
import java.io.*;
import com.fasterxml.jackson.core.*;
/**
* Unit tests for verifying that support for (non-standard) comments
* works as expected.
*/
public class CommentParsingTest
extends com.fasterxml.jackson.core.BaseTest
{
final static String DOC_WITH_SLASHSTAR_COMMENT =
"[ /* comment:\n ends here */ 1 /* one more ok to have \"unquoted\" */ ]"
;
final static String DOC_WITH_SLASHSLASH_COMMENT =
"[ // comment...\n 1 \r // one more, not array: [] \n ]"
;
/*
/**********************************************************
/* Test method wrappers
/**********************************************************
*/
/**
* Unit test for verifying that by default comments are not
* recognized.
*/
public void testDefaultSettings() throws Exception
{
JsonFactory jf = new JsonFactory();
assertFalse(jf.isEnabled(JsonParser.Feature.ALLOW_COMMENTS));
JsonParser p = jf.createParser(new StringReader("[ 1 ]"));
assertFalse(p.isEnabled(JsonParser.Feature.ALLOW_COMMENTS));
p.close();
}
public void testCommentsDisabled() throws Exception
{
_testDisabled(DOC_WITH_SLASHSTAR_COMMENT, MODE_INPUT_STREAM);
_testDisabled(DOC_WITH_SLASHSLASH_COMMENT, MODE_INPUT_STREAM);
_testDisabled(DOC_WITH_SLASHSTAR_COMMENT, MODE_INPUT_STREAM_THROTTLED);
_testDisabled(DOC_WITH_SLASHSLASH_COMMENT, MODE_INPUT_STREAM_THROTTLED);
_testDisabled(DOC_WITH_SLASHSTAR_COMMENT, MODE_READER);
_testDisabled(DOC_WITH_SLASHSLASH_COMMENT, MODE_READER);
_testDisabled(DOC_WITH_SLASHSTAR_COMMENT, MODE_DATA_INPUT);
_testDisabled(DOC_WITH_SLASHSLASH_COMMENT, MODE_DATA_INPUT);
}
public void testCommentsEnabled() throws Exception
{
_testEnabled(DOC_WITH_SLASHSTAR_COMMENT, MODE_INPUT_STREAM);
_testEnabled(DOC_WITH_SLASHSLASH_COMMENT, MODE_INPUT_STREAM);
_testEnabled(DOC_WITH_SLASHSTAR_COMMENT, MODE_INPUT_STREAM_THROTTLED);
_testEnabled(DOC_WITH_SLASHSLASH_COMMENT, MODE_INPUT_STREAM_THROTTLED);
_testEnabled(DOC_WITH_SLASHSTAR_COMMENT, MODE_READER);
_testEnabled(DOC_WITH_SLASHSLASH_COMMENT, MODE_READER);
_testEnabled(DOC_WITH_SLASHSTAR_COMMENT, MODE_DATA_INPUT);
_testEnabled(DOC_WITH_SLASHSLASH_COMMENT, MODE_DATA_INPUT);
}
public void testCommentsWithUTF8() throws Exception
{
final String JSON = "/* \u00a9 2099 Yoyodyne Inc. */\n [ \"bar? \u00a9\" ]\n";
_testWithUTF8Chars(JSON, MODE_INPUT_STREAM);
_testWithUTF8Chars(JSON, MODE_INPUT_STREAM_THROTTLED);
_testWithUTF8Chars(JSON, MODE_READER);
_testWithUTF8Chars(JSON, MODE_DATA_INPUT);
}
public void testYAMLCommentsBytes() throws Exception {
JsonFactory f = new JsonFactory();
f.configure(JsonParser.Feature.ALLOW_YAML_COMMENTS, true);
_testYAMLComments(f, MODE_INPUT_STREAM);
_testCommentsBeforePropValue(f, MODE_INPUT_STREAM, "# foo\n");
_testYAMLComments(f, MODE_INPUT_STREAM_THROTTLED);
_testCommentsBeforePropValue(f, MODE_INPUT_STREAM_THROTTLED, "# foo\n");
_testYAMLComments(f, MODE_DATA_INPUT);
_testCommentsBeforePropValue(f, MODE_DATA_INPUT, "# foo\n");
}
public void testYAMLCommentsChars() throws Exception {
JsonFactory f = new JsonFactory();
f.configure(JsonParser.Feature.ALLOW_YAML_COMMENTS, true);
_testYAMLComments(f, MODE_READER);
final String COMMENT = "# foo\n";
_testCommentsBeforePropValue(f, MODE_READER, COMMENT);
_testCommentsBetweenArrayValues(f, MODE_READER, COMMENT);
}
public void testCCommentsBytes() throws Exception {
JsonFactory f = new JsonFactory();
f.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
final String COMMENT = "/* foo */\n";
_testCommentsBeforePropValue(f, MODE_INPUT_STREAM, COMMENT);
_testCommentsBeforePropValue(f, MODE_INPUT_STREAM_THROTTLED, COMMENT);
_testCommentsBeforePropValue(f, MODE_DATA_INPUT, COMMENT);
}
public void testCCommentsChars() throws Exception {
JsonFactory f = new JsonFactory();
f.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
final String COMMENT = "/* foo */\n";
_testCommentsBeforePropValue(f, MODE_READER, COMMENT);
}
public void testCppCommentsBytes() throws Exception {
JsonFactory f = new JsonFactory();
f.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
final String COMMENT = "// foo\n";
_testCommentsBeforePropValue(f, MODE_INPUT_STREAM, COMMENT);
_testCommentsBeforePropValue(f, MODE_INPUT_STREAM_THROTTLED, COMMENT);
_testCommentsBeforePropValue(f, MODE_DATA_INPUT, COMMENT);
}
public void testCppCommentsChars() throws Exception {
JsonFactory f = new JsonFactory();
f.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
final String COMMENT = "// foo \n";
_testCommentsBeforePropValue(f, MODE_READER, COMMENT);
}
@SuppressWarnings("resource")
private void _testCommentsBeforePropValue(JsonFactory f,
int mode, String comment) throws Exception
{
for (String arg : new String[] {
":%s123",
" :%s123",
"\t:%s123",
": %s123",
":\t%s123",
}) {
String commented = String.format(arg, comment);
final String DOC = "{\"abc\"" + commented + "}";
JsonParser p = createParser(f, mode, DOC);
assertEquals(JsonToken.START_OBJECT, p.nextToken());
JsonToken t = null;
try {
t = p.nextToken();
} catch (Exception e) {
throw new RuntimeException("Failed on '"+DOC+"' due to "+e, e);
}
assertEquals(JsonToken.FIELD_NAME, t);
try {
t = p.nextToken();
} catch (Exception e) {
throw new RuntimeException("Failed on '"+DOC+"' due to "+e, e);
}
assertEquals(JsonToken.VALUE_NUMBER_INT, t);
assertEquals(123, p.getIntValue());
assertEquals(JsonToken.END_OBJECT, p.nextToken());
p.close();
}
}
@SuppressWarnings("resource")
private void _testCommentsBetweenArrayValues(JsonFactory f,
int mode, String comment) throws Exception
{
for (String tmpl : new String[] {
"%s,",
" %s,",
"\t%s,",
"%s ,",
"%s\t,",
" %s ,",
"\t%s\t,",
"\n%s,",
"%s\n,",
}) {
String commented = String.format(tmpl, comment);
final String DOC = "[1"+commented+"2]";
JsonParser p = createParser(f, mode, DOC);
assertEquals(JsonToken.START_ARRAY, p.nextToken());
JsonToken t = null;
try {
t = p.nextToken();
} catch (Exception e) {
throw new RuntimeException("Failed on '"+DOC+"' due to "+e, e);
}
assertEquals(JsonToken.VALUE_NUMBER_INT, t);
assertEquals(1, p.getIntValue());
try {
t = p.nextToken();
} catch (Exception e) {
throw new RuntimeException("Failed on '"+DOC+"' due to "+e, e);
}
assertEquals(JsonToken.VALUE_NUMBER_INT, t);
assertEquals(2, p.getIntValue());
assertEquals(JsonToken.END_ARRAY, p.nextToken());
p.close();
}
}
private void _testYAMLComments(JsonFactory f, int mode) throws Exception
{
final String DOC = "# foo\n"
+" {\"a\" # xyz\n"
+" : # foo\n"
+" 1, # more\n"
+"\"b\": [ \n"
+" #all!\n"
+" 3 #yay!\n"
+"] # foobar\n"
+"} # x"
;
JsonParser p = createParser(f, mode, DOC);
assertEquals(JsonToken.START_OBJECT, p.nextToken());
assertEquals(JsonToken.FIELD_NAME, p.nextToken());
assertEquals("a", p.getCurrentName());
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(1, p.getIntValue());
assertEquals(JsonToken.FIELD_NAME, p.nextToken());
assertEquals("b", p.getCurrentName());
assertEquals(JsonToken.START_ARRAY, p.nextToken());
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(3, p.getIntValue());
assertEquals(JsonToken.END_ARRAY, p.nextToken());
assertEquals(JsonToken.END_OBJECT, p.nextToken());
if (mode != MODE_DATA_INPUT) {
assertNull(p.nextToken());
}
p.close();
}
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
private void _testWithUTF8Chars(String doc, int mode) throws IOException
{
// should basically just stream through
JsonParser p = _createParser(doc, mode, true);
assertToken(JsonToken.VALUE_STRING, p.nextToken());
assertToken(JsonToken.END_ARRAY, p.nextToken());
if (mode != MODE_DATA_INPUT) {
assertNull(p.nextToken());
}
p.close();
}
private void _testDisabled(String doc, int mode) throws IOException
{
JsonParser p = _createParser(doc, mode, false);
try {
p.nextToken();
fail("Expected exception for unrecognized comment");
} catch (JsonParseException je) {
// Should have something denoting that user may want to enable 'ALLOW_COMMENTS'
verifyException(je, "ALLOW_COMMENTS");
}
p.close();
}
private void _testEnabled(String doc, int mode) throws IOException
{
JsonParser p = _createParser(doc, mode, true);
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(1, p.getIntValue());
assertToken(JsonToken.END_ARRAY, p.nextToken());
p.close();
}
private JsonParser _createParser(String doc, int mode, boolean enabled)
throws IOException
{
JsonFactory f = new JsonFactory();
f.configure(JsonParser.Feature.ALLOW_COMMENTS, enabled);
JsonParser p = createParser(f, mode, doc);
assertToken(JsonToken.START_ARRAY, p.nextToken());
return p;
}
}