blob: de36df29845043b7d0fc67410d428f49d2e89a7a [file] [log] [blame]
cowtowncoderba364612008-03-24 05:59:43 +00001package main;
2
3import org.codehaus.jackson.*;
4
5import java.io.IOException;
6
7/**
8 * Set of basic unit tests for verifying that the basic parser
9 * functionality works as expected.
10 */
11public class TestJsonParser
12 extends BaseTest
13{
14
15 /**
16 * This basic unit test verifies that example given in the Json
17 * specification (RFC-4627 or later) is properly parsed at
18 * high-level, without verifying values.
19 */
20 public void testSpecExampleSkipping()
21 throws Exception
22 {
23 doTestSpec(false);
24 }
25
26 /**
27 * Unit test that verifies that the spec example JSON is completely
28 * parsed, and proper values are given for contents of all
29 * events/tokens.
30 */
31 public void testSpecExampleFully()
32 throws Exception
33 {
34 doTestSpec(true);
35 }
36
37 /**
38 * Unit test that verifies that 3 basic keywords (null, true, false)
39 * are properly parsed in various contexts.
40 */
41 public void testKeywords()
42 throws Exception
43 {
44 final String DOC = "{\n"
45 +"\"key1\" : null,\n"
46 +"\"key2\" : true,\n"
47 +"\"key3\" : false,\n"
48 +"\"key4\" : [ false, null, true ]\n"
49 +"}"
50 ;
51
52 JsonParser jp = createParserUsingStream(DOC, "UTF-8");
53 assertToken(JsonToken.START_OBJECT, jp.nextToken());
54
55 assertToken(JsonToken.FIELD_NAME, jp.nextToken());
56 verifyFieldName(jp, "key1");
57 assertToken(JsonToken.VALUE_NULL, jp.nextToken());
58
59 assertToken(JsonToken.FIELD_NAME, jp.nextToken());
60 verifyFieldName(jp, "key2");
61 assertToken(JsonToken.VALUE_TRUE, jp.nextToken());
62
63 assertToken(JsonToken.FIELD_NAME, jp.nextToken());
64 verifyFieldName(jp, "key3");
65 assertToken(JsonToken.VALUE_FALSE, jp.nextToken());
66
67 assertToken(JsonToken.FIELD_NAME, jp.nextToken());
68 verifyFieldName(jp, "key4");
69 assertToken(JsonToken.START_ARRAY, jp.nextToken());
70 assertToken(JsonToken.VALUE_FALSE, jp.nextToken());
71 assertToken(JsonToken.VALUE_NULL, jp.nextToken());
72 assertToken(JsonToken.VALUE_TRUE, jp.nextToken());
73 assertToken(JsonToken.END_ARRAY, jp.nextToken());
74
75 assertToken(JsonToken.END_OBJECT, jp.nextToken());
76 }
77
78 public void testInvalidKeywords()
79 throws Exception
80 {
81 doTestInvalidKeyword1("nul");
82 doTestInvalidKeyword2("nulla", JsonToken.VALUE_NULL);
83 doTestInvalidKeyword1("fal");
84 doTestInvalidKeyword3("False");
85 doTestInvalidKeyword2("falsett0", JsonToken.VALUE_FALSE);
86 doTestInvalidKeyword1("tr");
87 doTestInvalidKeyword1("truE");
88 doTestInvalidKeyword2("trueenough", JsonToken.VALUE_TRUE);
89 }
90
91 /*
92 /////////////////////////////////////////////
93 // Helper methods
94 /////////////////////////////////////////////
95 */
96
97 private void doTestSpec(boolean verify)
98 throws IOException
99 {
100 // First, using a StringReader:
101 doTestSpecIndividual(null, verify);
102
103 // Then with streams using supported encodings:
104 doTestSpecIndividual("UTF-8", verify);
105 doTestSpecIndividual("UTF-16BE", verify);
106 doTestSpecIndividual("UTF-16LE", verify);
107
108 /* Hmmh. UTF-32 is harder only because JDK doesn't come with
109 * a codec for it. Can't test it yet using this method
110 */
111 //doTestSpecIndividual("UTF-32", verify);
112 }
113
114 private void doTestSpecIndividual(String enc, boolean verify)
115 throws IOException
116 {
117 String doc = SAMPLE_DOC_JSON_SPEC;
118 JsonParser jp;
119
120 if (enc == null) {
121 jp = createParserUsingReader(doc);
122 } else {
123 jp = createParserUsingStream(doc, enc);
124 }
125
126 assertToken(JsonToken.START_OBJECT, jp.nextToken()); // main object
127
128 assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Image'
129 if (verify) {
130 verifyFieldName(jp, "Image");
131 }
132
133 assertToken(JsonToken.START_OBJECT, jp.nextToken()); // 'image' object
134
135 assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Width'
136 if (verify) {
137 verifyFieldName(jp, "Width");
138 }
139
140 assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
141 if (verify) {
142 verifyIntValue(jp, SAMPLE_SPEC_VALUE_WIDTH);
143 }
144
145 assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Height'
146 if (verify) {
147 verifyFieldName(jp, "Height");
148 }
149
150 assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
151 verifyIntValue(jp, SAMPLE_SPEC_VALUE_HEIGHT);
152 assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Title'
153 if (verify) {
154 verifyFieldName(jp, "Title");
155 }
156 assertToken(JsonToken.VALUE_STRING, jp.nextToken());
157 assertEquals(SAMPLE_SPEC_VALUE_TITLE, getAndVerifyText(jp));
158 assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Thumbnail'
159 if (verify) {
160 verifyFieldName(jp, "Thumbnail");
161 }
162
163 assertToken(JsonToken.START_OBJECT, jp.nextToken()); // 'thumbnail' object
164 assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Url'
165 if (verify) {
166 verifyFieldName(jp, "Url");
167 }
168 assertToken(JsonToken.VALUE_STRING, jp.nextToken());
169 if (verify) {
170 assertEquals(SAMPLE_SPEC_VALUE_TN_URL, getAndVerifyText(jp));
171 }
172 assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Height'
173 if (verify) {
174 verifyFieldName(jp, "Height");
175 }
176 assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
177 verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_HEIGHT);
178 assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'Width'
179 if (verify) {
180 verifyFieldName(jp, "Width");
181 }
182 // Width value is actually a String in the example
183 assertToken(JsonToken.VALUE_STRING, jp.nextToken());
184 assertEquals(SAMPLE_SPEC_VALUE_TN_WIDTH, getAndVerifyText(jp));
185
186 assertToken(JsonToken.END_OBJECT, jp.nextToken()); // 'thumbnail' object
187
188 assertToken(JsonToken.FIELD_NAME, jp.nextToken()); // 'IDs'
189 assertToken(JsonToken.START_ARRAY, jp.nextToken()); // 'ids' array
190 assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); // ids[0]
191 verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID1);
192 assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); // ids[1]
193 verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID2);
194 assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); // ids[2]
195 verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID3);
196 assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); // ids[3]
197 verifyIntValue(jp, SAMPLE_SPEC_VALUE_TN_ID4);
198 assertToken(JsonToken.END_ARRAY, jp.nextToken()); // 'ids' array
199
200 assertToken(JsonToken.END_OBJECT, jp.nextToken()); // 'image' object
201
202 assertToken(JsonToken.END_OBJECT, jp.nextToken()); // main object
203 }
204
205 private void verifyFieldName(JsonParser jp, String expName)
206 throws IOException
207 {
208 assertEquals(expName, jp.getText());
209 assertEquals(expName, jp.getCurrentName());
210 }
211
212 private void verifyIntValue(JsonParser jp, long expValue)
213 throws IOException
214 {
215 // First, via textual
216 assertEquals(String.valueOf(expValue), jp.getText());
217 }
218
219 private void doTestInvalidKeyword1(String value)
220 throws IOException
221 {
222 JsonParser jp = createParserUsingStream("{ \"key1\" : "+value+" }", "UTF-8");
223 assertToken(JsonToken.START_OBJECT, jp.nextToken());
224 assertToken(JsonToken.FIELD_NAME, jp.nextToken());
225 try {
226 jp.nextToken();
227 fail("Expected an exception for malformed value keyword");
228 } catch (JsonParseException jex) {
229 verifyException(jex, "Unrecognized token");
230 }
231 }
232
233 private void doTestInvalidKeyword2(String value, JsonToken firstValue)
234 throws IOException
235 {
236 JsonParser jp = createParserUsingStream("{ \"key1\" : "+value+" }", "UTF-8");
237 assertToken(JsonToken.START_OBJECT, jp.nextToken());
238 assertToken(JsonToken.FIELD_NAME, jp.nextToken());
239 assertToken(firstValue, jp.nextToken());
240 try {
241 jp.nextToken();
242 fail("Expected an exception for malformed value keyword");
243 } catch (JsonParseException jex) {
244 verifyException(jex, "Unexpected character");
245 }
246 }
247
248 private void doTestInvalidKeyword3(String value)
249 throws IOException
250 {
251 JsonParser jp = createParserUsingStream("{ \"key1\" : "+value+" }", "UTF-8");
252 assertToken(JsonToken.START_OBJECT, jp.nextToken());
253 assertToken(JsonToken.FIELD_NAME, jp.nextToken());
254 try {
255 jp.nextToken();
256 fail("Expected an exception for malformed value keyword");
257 } catch (JsonParseException jex) {
258 verifyException(jex, "expected a valid value");
259 }
260 }
261}
262