Checking in Jackson 0.9.1 baseline.
diff --git a/src/test/main/TestJsonParser.java b/src/test/main/TestJsonParser.java
new file mode 100644
index 0000000..de36df2
--- /dev/null
+++ b/src/test/main/TestJsonParser.java
@@ -0,0 +1,262 @@
+package main;
+
+import org.codehaus.jackson.*;
+
+import java.io.IOException;
+
+/**
+ * Set of basic unit tests for verifying that the basic parser
+ * functionality works as expected.
+ */
+public class TestJsonParser
+ extends BaseTest
+{
+
+ /**
+ * This basic unit test verifies that example given in the Json
+ * specification (RFC-4627 or later) is properly parsed at
+ * high-level, without verifying values.
+ */
+ public void testSpecExampleSkipping()
+ throws Exception
+ {
+ doTestSpec(false);
+ }
+
+ /**
+ * Unit test that verifies that the spec example JSON is completely
+ * parsed, and proper values are given for contents of all
+ * events/tokens.
+ */
+ public void testSpecExampleFully()
+ throws Exception
+ {
+ doTestSpec(true);
+ }
+
+ /**
+ * Unit test that verifies that 3 basic keywords (null, true, false)
+ * are properly parsed in various contexts.
+ */
+ public void testKeywords()
+ throws Exception
+ {
+ final String DOC = "{\n"
+ +"\"key1\" : null,\n"
+ +"\"key2\" : true,\n"
+ +"\"key3\" : false,\n"
+ +"\"key4\" : [ false, null, true ]\n"
+ +"}"
+ ;
+
+ JsonParser jp = createParserUsingStream(DOC, "UTF-8");
+ assertToken(JsonToken.START_OBJECT, jp.nextToken());
+
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken());
+ verifyFieldName(jp, "key1");
+ assertToken(JsonToken.VALUE_NULL, jp.nextToken());
+
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken());
+ verifyFieldName(jp, "key2");
+ assertToken(JsonToken.VALUE_TRUE, jp.nextToken());
+
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken());
+ verifyFieldName(jp, "key3");
+ assertToken(JsonToken.VALUE_FALSE, jp.nextToken());
+
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken());
+ verifyFieldName(jp, "key4");
+ assertToken(JsonToken.START_ARRAY, jp.nextToken());
+ assertToken(JsonToken.VALUE_FALSE, jp.nextToken());
+ assertToken(JsonToken.VALUE_NULL, jp.nextToken());
+ assertToken(JsonToken.VALUE_TRUE, jp.nextToken());
+ assertToken(JsonToken.END_ARRAY, jp.nextToken());
+
+ assertToken(JsonToken.END_OBJECT, jp.nextToken());
+ }
+
+ public void testInvalidKeywords()
+ throws Exception
+ {
+ doTestInvalidKeyword1("nul");
+ doTestInvalidKeyword2("nulla", JsonToken.VALUE_NULL);
+ doTestInvalidKeyword1("fal");
+ doTestInvalidKeyword3("False");
+ doTestInvalidKeyword2("falsett0", JsonToken.VALUE_FALSE);
+ doTestInvalidKeyword1("tr");
+ doTestInvalidKeyword1("truE");
+ doTestInvalidKeyword2("trueenough", JsonToken.VALUE_TRUE);
+ }
+
+ /*
+ /////////////////////////////////////////////
+ // Helper methods
+ /////////////////////////////////////////////
+ */
+
+ private void doTestSpec(boolean verify)
+ throws IOException
+ {
+ // First, using a StringReader:
+ doTestSpecIndividual(null, verify);
+
+ // Then with streams using supported encodings:
+ doTestSpecIndividual("UTF-8", verify);
+ doTestSpecIndividual("UTF-16BE", verify);
+ doTestSpecIndividual("UTF-16LE", verify);
+
+ /* Hmmh. UTF-32 is harder only because JDK doesn't come with
+ * a codec for it. Can't test it yet using this method
+ */
+ //doTestSpecIndividual("UTF-32", verify);
+ }
+
+ private void doTestSpecIndividual(String enc, boolean verify)
+ throws IOException
+ {
+ String doc = SAMPLE_DOC_JSON_SPEC;
+ JsonParser jp;
+
+ if (enc == null) {
+ jp = createParserUsingReader(doc);
+ } else {
+ jp = createParserUsingStream(doc, enc);
+ }
+
+ assertToken(JsonToken.START_OBJECT, jp.nextToken()); // main object
+
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Image'
+ if (verify) {
+ verifyFieldName(jp, "Image");
+ }
+
+ assertToken(JsonToken.START_OBJECT, jp.nextToken()); // 'image' object
+
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Width'
+ if (verify) {
+ verifyFieldName(jp, "Width");
+ }
+
+ assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
+ if (verify) {
+ verifyIntValue(jp, SAMPLE_SPEC_VALUE_WIDTH);
+ }
+
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Height'
+ if (verify) {
+ verifyFieldName(jp, "Height");
+ }
+
+ assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
+ verifyIntValue(jp, SAMPLE_SPEC_VALUE_HEIGHT);
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Title'
+ if (verify) {
+ verifyFieldName(jp, "Title");
+ }
+ assertToken(JsonToken.VALUE_STRING, jp.nextToken());
+ assertEquals(SAMPLE_SPEC_VALUE_TITLE, getAndVerifyText(jp));
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Thumbnail'
+ if (verify) {
+ verifyFieldName(jp, "Thumbnail");
+ }
+
+ assertToken(JsonToken.START_OBJECT, jp.nextToken()); // 'thumbnail' object
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Url'
+ if (verify) {
+ verifyFieldName(jp, "Url");
+ }
+ assertToken(JsonToken.VALUE_STRING, jp.nextToken());
+ if (verify) {
+ assertEquals(SAMPLE_SPEC_VALUE_TN_URL, getAndVerifyText(jp));
+ }
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Height'
+ if (verify) {
+ verifyFieldName(jp, "Height");
+ }
+ assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
+ verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_HEIGHT);
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Width'
+ if (verify) {
+ verifyFieldName(jp, "Width");
+ }
+ // Width value is actually a String in the example
+ assertToken(JsonToken.VALUE_STRING, jp.nextToken());
+ assertEquals(SAMPLE_SPEC_VALUE_TN_WIDTH, getAndVerifyText(jp));
+
+ assertToken(JsonToken.END_OBJECT, jp.nextToken()); // 'thumbnail' object
+
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'IDs'
+ assertToken(JsonToken.START_ARRAY, jp.nextToken()); // 'ids' array
+ assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); // ids[0]
+ verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID1);
+ assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); // ids[1]
+ verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID2);
+ assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); // ids[2]
+ verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID3);
+ assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); // ids[3]
+ verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID4);
+ assertToken(JsonToken.END_ARRAY, jp.nextToken()); // 'ids' array
+
+ assertToken(JsonToken.END_OBJECT, jp.nextToken()); // 'image' object
+
+ assertToken(JsonToken.END_OBJECT, jp.nextToken()); // main object
+ }
+
+ private void verifyFieldName(JsonParser jp, String expName)
+ throws IOException
+ {
+ assertEquals(expName, jp.getText());
+ assertEquals(expName, jp.getCurrentName());
+ }
+
+ private void verifyIntValue(JsonParser jp, long expValue)
+ throws IOException
+ {
+ // First, via textual
+ assertEquals(String.valueOf(expValue), jp.getText());
+ }
+
+ private void doTestInvalidKeyword1(String value)
+ throws IOException
+ {
+ JsonParser jp = createParserUsingStream("{ \"key1\" : "+value+" }", "UTF-8");
+ assertToken(JsonToken.START_OBJECT, jp.nextToken());
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken());
+ try {
+ jp.nextToken();
+ fail("Expected an exception for malformed value keyword");
+ } catch (JsonParseException jex) {
+ verifyException(jex, "Unrecognized token");
+ }
+ }
+
+ private void doTestInvalidKeyword2(String value, JsonToken firstValue)
+ throws IOException
+ {
+ JsonParser jp = createParserUsingStream("{ \"key1\" : "+value+" }", "UTF-8");
+ assertToken(JsonToken.START_OBJECT, jp.nextToken());
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken());
+ assertToken(firstValue, jp.nextToken());
+ try {
+ jp.nextToken();
+ fail("Expected an exception for malformed value keyword");
+ } catch (JsonParseException jex) {
+ verifyException(jex, "Unexpected character");
+ }
+ }
+
+ private void doTestInvalidKeyword3(String value)
+ throws IOException
+ {
+ JsonParser jp = createParserUsingStream("{ \"key1\" : "+value+" }", "UTF-8");
+ assertToken(JsonToken.START_OBJECT, jp.nextToken());
+ assertToken(JsonToken.FIELD_NAME, jp.nextToken());
+ try {
+ jp.nextToken();
+ fail("Expected an exception for malformed value keyword");
+ } catch (JsonParseException jex) {
+ verifyException(jex, "expected a valid value");
+ }
+ }
+}
+