1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.util;
18
19import java.io.IOException;
20import java.io.StringWriter;
21import java.math.BigDecimal;
22import java.math.BigInteger;
23import junit.framework.TestCase;
24
25public final class JsonWriterTest extends TestCase {
26
27    public void testWrongTopLevelType() throws IOException {
28        StringWriter stringWriter = new StringWriter();
29        JsonWriter jsonWriter = new JsonWriter(stringWriter);
30        try {
31            jsonWriter.value("a");
32            fail();
33        } catch (IllegalStateException expected) {
34        }
35    }
36
37    public void testTwoNames() throws IOException {
38        StringWriter stringWriter = new StringWriter();
39        JsonWriter jsonWriter = new JsonWriter(stringWriter);
40        jsonWriter.beginObject();
41        jsonWriter.name("a");
42        try {
43            jsonWriter.name("a");
44            fail();
45        } catch (IllegalStateException expected) {
46        }
47    }
48
49    public void testNameWithoutValue() throws IOException {
50        StringWriter stringWriter = new StringWriter();
51        JsonWriter jsonWriter = new JsonWriter(stringWriter);
52        jsonWriter.beginObject();
53        jsonWriter.name("a");
54        try {
55            jsonWriter.endObject();
56            fail();
57        } catch (IllegalStateException expected) {
58        }
59    }
60
61    public void testValueWithoutName() throws IOException {
62        StringWriter stringWriter = new StringWriter();
63        JsonWriter jsonWriter = new JsonWriter(stringWriter);
64        jsonWriter.beginObject();
65        try {
66            jsonWriter.value(true);
67            fail();
68        } catch (IllegalStateException expected) {
69        }
70    }
71
72    public void testMultipleTopLevelValues() throws IOException {
73        StringWriter stringWriter = new StringWriter();
74        JsonWriter jsonWriter = new JsonWriter(stringWriter);
75        jsonWriter.beginArray().endArray();
76        try {
77            jsonWriter.beginArray();
78            fail();
79        } catch (IllegalStateException expected) {
80        }
81    }
82
83    public void testBadNestingObject() throws IOException {
84        StringWriter stringWriter = new StringWriter();
85        JsonWriter jsonWriter = new JsonWriter(stringWriter);
86        jsonWriter.beginArray();
87        jsonWriter.beginObject();
88        try {
89            jsonWriter.endArray();
90            fail();
91        } catch (IllegalStateException expected) {
92        }
93    }
94
95    public void testBadNestingArray() throws IOException {
96        StringWriter stringWriter = new StringWriter();
97        JsonWriter jsonWriter = new JsonWriter(stringWriter);
98        jsonWriter.beginArray();
99        jsonWriter.beginArray();
100        try {
101            jsonWriter.endObject();
102            fail();
103        } catch (IllegalStateException expected) {
104        }
105    }
106
107    public void testNullName() throws IOException {
108        StringWriter stringWriter = new StringWriter();
109        JsonWriter jsonWriter = new JsonWriter(stringWriter);
110        jsonWriter.beginObject();
111        try {
112            jsonWriter.name(null);
113            fail();
114        } catch (NullPointerException expected) {
115        }
116    }
117
118    public void testNullStringValue() throws IOException {
119        StringWriter stringWriter = new StringWriter();
120        JsonWriter jsonWriter = new JsonWriter(stringWriter);
121        jsonWriter.beginObject();
122        jsonWriter.name("a");
123        jsonWriter.value((String) null);
124        jsonWriter.endObject();
125        assertEquals("{\"a\":null}", stringWriter.toString());
126    }
127
128    public void testNonFiniteDoubles() throws IOException {
129        StringWriter stringWriter = new StringWriter();
130        JsonWriter jsonWriter = new JsonWriter(stringWriter);
131        jsonWriter.beginArray();
132        try {
133            jsonWriter.value(Double.NaN);
134            fail();
135        } catch (IllegalArgumentException expected) {
136        }
137        try {
138            jsonWriter.value(Double.NEGATIVE_INFINITY);
139            fail();
140        } catch (IllegalArgumentException expected) {
141        }
142        try {
143            jsonWriter.value(Double.POSITIVE_INFINITY);
144            fail();
145        } catch (IllegalArgumentException expected) {
146        }
147    }
148
149    public void testNonFiniteBoxedDoubles() throws IOException {
150        StringWriter stringWriter = new StringWriter();
151        JsonWriter jsonWriter = new JsonWriter(stringWriter);
152        jsonWriter.beginArray();
153        try {
154            jsonWriter.value(new Double(Double.NaN));
155            fail();
156        } catch (IllegalArgumentException expected) {
157        }
158        try {
159            jsonWriter.value(new Double(Double.NEGATIVE_INFINITY));
160            fail();
161        } catch (IllegalArgumentException expected) {
162        }
163        try {
164            jsonWriter.value(new Double(Double.POSITIVE_INFINITY));
165            fail();
166        } catch (IllegalArgumentException expected) {
167        }
168    }
169
170    public void testDoubles() throws IOException {
171        StringWriter stringWriter = new StringWriter();
172        JsonWriter jsonWriter = new JsonWriter(stringWriter);
173        jsonWriter.beginArray();
174        jsonWriter.value(-0.0);
175        jsonWriter.value(1.0);
176        jsonWriter.value(Double.MAX_VALUE);
177        jsonWriter.value(Double.MIN_VALUE);
178        jsonWriter.value(0.0);
179        jsonWriter.value(-0.5);
180        jsonWriter.value(Double.MIN_NORMAL);
181        jsonWriter.value(Math.PI);
182        jsonWriter.value(Math.E);
183        jsonWriter.endArray();
184        jsonWriter.close();
185        assertEquals("[-0.0,"
186                + "1.0,"
187                + "1.7976931348623157E308,"
188                + "4.9E-324,"
189                + "0.0,"
190                + "-0.5,"
191                + "2.2250738585072014E-308,"
192                + "3.141592653589793,"
193                + "2.718281828459045]", stringWriter.toString());
194    }
195
196    public void testLongs() throws IOException {
197        StringWriter stringWriter = new StringWriter();
198        JsonWriter jsonWriter = new JsonWriter(stringWriter);
199        jsonWriter.beginArray();
200        jsonWriter.value(0);
201        jsonWriter.value(1);
202        jsonWriter.value(-1);
203        jsonWriter.value(Long.MIN_VALUE);
204        jsonWriter.value(Long.MAX_VALUE);
205        jsonWriter.endArray();
206        jsonWriter.close();
207        assertEquals("[0,"
208                + "1,"
209                + "-1,"
210                + "-9223372036854775808,"
211                + "9223372036854775807]", stringWriter.toString());
212    }
213
214    public void testNumbers() throws IOException {
215        StringWriter stringWriter = new StringWriter();
216        JsonWriter jsonWriter = new JsonWriter(stringWriter);
217        jsonWriter.beginArray();
218        jsonWriter.value(new BigInteger("0"));
219        jsonWriter.value(new BigInteger("9223372036854775808"));
220        jsonWriter.value(new BigInteger("-9223372036854775809"));
221        jsonWriter.value(new BigDecimal("3.141592653589793238462643383"));
222        jsonWriter.endArray();
223        jsonWriter.close();
224        assertEquals("[0,"
225                + "9223372036854775808,"
226                + "-9223372036854775809,"
227                + "3.141592653589793238462643383]", stringWriter.toString());
228    }
229
230    public void testBooleans() throws IOException {
231        StringWriter stringWriter = new StringWriter();
232        JsonWriter jsonWriter = new JsonWriter(stringWriter);
233        jsonWriter.beginArray();
234        jsonWriter.value(true);
235        jsonWriter.value(false);
236        jsonWriter.endArray();
237        assertEquals("[true,false]", stringWriter.toString());
238    }
239
240    public void testNulls() throws IOException {
241        StringWriter stringWriter = new StringWriter();
242        JsonWriter jsonWriter = new JsonWriter(stringWriter);
243        jsonWriter.beginArray();
244        jsonWriter.nullValue();
245        jsonWriter.endArray();
246        assertEquals("[null]", stringWriter.toString());
247    }
248
249    public void testStrings() throws IOException {
250        StringWriter stringWriter = new StringWriter();
251        JsonWriter jsonWriter = new JsonWriter(stringWriter);
252        jsonWriter.beginArray();
253        jsonWriter.value("a");
254        jsonWriter.value("a\"");
255        jsonWriter.value("\"");
256        jsonWriter.value(":");
257        jsonWriter.value(",");
258        jsonWriter.value("\b");
259        jsonWriter.value("\f");
260        jsonWriter.value("\n");
261        jsonWriter.value("\r");
262        jsonWriter.value("\t");
263        jsonWriter.value(" ");
264        jsonWriter.value("\\");
265        jsonWriter.value("{");
266        jsonWriter.value("}");
267        jsonWriter.value("[");
268        jsonWriter.value("]");
269        jsonWriter.value("\0");
270        jsonWriter.value("\u0019");
271        jsonWriter.endArray();
272        assertEquals("[\"a\","
273                + "\"a\\\"\","
274                + "\"\\\"\","
275                + "\":\","
276                + "\",\","
277                + "\"\\b\","
278                + "\"\\f\","
279                + "\"\\n\","
280                + "\"\\r\","
281                + "\"\\t\","
282                + "\" \","
283                + "\"\\\\\","
284                + "\"{\","
285                + "\"}\","
286                + "\"[\","
287                + "\"]\","
288                + "\"\\u0000\","
289                + "\"\\u0019\"]", stringWriter.toString());
290    }
291
292    public void testUnicodeLineBreaksEscaped() throws IOException {
293        StringWriter stringWriter = new StringWriter();
294        JsonWriter jsonWriter = new JsonWriter(stringWriter);
295        jsonWriter.beginArray();
296        jsonWriter.value("\u2028 \u2029");
297        jsonWriter.endArray();
298        assertEquals("[\"\\u2028 \\u2029\"]", stringWriter.toString());
299    }
300
301    public void testEmptyArray() throws IOException {
302        StringWriter stringWriter = new StringWriter();
303        JsonWriter jsonWriter = new JsonWriter(stringWriter);
304        jsonWriter.beginArray();
305        jsonWriter.endArray();
306        assertEquals("[]", stringWriter.toString());
307    }
308
309    public void testEmptyObject() throws IOException {
310        StringWriter stringWriter = new StringWriter();
311        JsonWriter jsonWriter = new JsonWriter(stringWriter);
312        jsonWriter.beginObject();
313        jsonWriter.endObject();
314        assertEquals("{}", stringWriter.toString());
315    }
316
317    public void testObjectsInArrays() throws IOException {
318        StringWriter stringWriter = new StringWriter();
319        JsonWriter jsonWriter = new JsonWriter(stringWriter);
320        jsonWriter.beginArray();
321        jsonWriter.beginObject();
322        jsonWriter.name("a").value(5);
323        jsonWriter.name("b").value(false);
324        jsonWriter.endObject();
325        jsonWriter.beginObject();
326        jsonWriter.name("c").value(6);
327        jsonWriter.name("d").value(true);
328        jsonWriter.endObject();
329        jsonWriter.endArray();
330        assertEquals("[{\"a\":5,\"b\":false},"
331                + "{\"c\":6,\"d\":true}]", stringWriter.toString());
332    }
333
334    public void testArraysInObjects() throws IOException {
335        StringWriter stringWriter = new StringWriter();
336        JsonWriter jsonWriter = new JsonWriter(stringWriter);
337        jsonWriter.beginObject();
338        jsonWriter.name("a");
339        jsonWriter.beginArray();
340        jsonWriter.value(5);
341        jsonWriter.value(false);
342        jsonWriter.endArray();
343        jsonWriter.name("b");
344        jsonWriter.beginArray();
345        jsonWriter.value(6);
346        jsonWriter.value(true);
347        jsonWriter.endArray();
348        jsonWriter.endObject();
349        assertEquals("{\"a\":[5,false],"
350                + "\"b\":[6,true]}", stringWriter.toString());
351    }
352
353    public void testDeepNestingArrays() throws IOException {
354        StringWriter stringWriter = new StringWriter();
355        JsonWriter jsonWriter = new JsonWriter(stringWriter);
356        for (int i = 0; i < 20; i++) {
357            jsonWriter.beginArray();
358        }
359        for (int i = 0; i < 20; i++) {
360            jsonWriter.endArray();
361        }
362        assertEquals("[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]", stringWriter.toString());
363    }
364
365    public void testDeepNestingObjects() throws IOException {
366        StringWriter stringWriter = new StringWriter();
367        JsonWriter jsonWriter = new JsonWriter(stringWriter);
368        jsonWriter.beginObject();
369        for (int i = 0; i < 20; i++) {
370            jsonWriter.name("a");
371            jsonWriter.beginObject();
372        }
373        for (int i = 0; i < 20; i++) {
374            jsonWriter.endObject();
375        }
376        jsonWriter.endObject();
377        assertEquals("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":"
378                + "{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{"
379                + "}}}}}}}}}}}}}}}}}}}}}", stringWriter.toString());
380    }
381
382    public void testRepeatedName() throws IOException {
383        StringWriter stringWriter = new StringWriter();
384        JsonWriter jsonWriter = new JsonWriter(stringWriter);
385        jsonWriter.beginObject();
386        jsonWriter.name("a").value(true);
387        jsonWriter.name("a").value(false);
388        jsonWriter.endObject();
389        // JsonWriter doesn't attempt to detect duplicate names
390        assertEquals("{\"a\":true,\"a\":false}", stringWriter.toString());
391    }
392
393    public void testPrettyPrintObject() throws IOException {
394        StringWriter stringWriter = new StringWriter();
395        JsonWriter jsonWriter = new JsonWriter(stringWriter);
396        jsonWriter.setIndent("   ");
397
398        jsonWriter.beginObject();
399        jsonWriter.name("a").value(true);
400        jsonWriter.name("b").value(false);
401        jsonWriter.name("c").value(5.0);
402        jsonWriter.name("e").nullValue();
403        jsonWriter.name("f").beginArray();
404        jsonWriter.value(6.0);
405        jsonWriter.value(7.0);
406        jsonWriter.endArray();
407        jsonWriter.name("g").beginObject();
408        jsonWriter.name("h").value(8.0);
409        jsonWriter.name("i").value(9.0);
410        jsonWriter.endObject();
411        jsonWriter.endObject();
412
413        String expected = "{\n"
414                + "   \"a\": true,\n"
415                + "   \"b\": false,\n"
416                + "   \"c\": 5.0,\n"
417                + "   \"e\": null,\n"
418                + "   \"f\": [\n"
419                + "      6.0,\n"
420                + "      7.0\n"
421                + "   ],\n"
422                + "   \"g\": {\n"
423                + "      \"h\": 8.0,\n"
424                + "      \"i\": 9.0\n"
425                + "   }\n"
426                + "}";
427        assertEquals(expected, stringWriter.toString());
428    }
429
430    public void testPrettyPrintArray() throws IOException {
431        StringWriter stringWriter = new StringWriter();
432        JsonWriter jsonWriter = new JsonWriter(stringWriter);
433        jsonWriter.setIndent("   ");
434
435        jsonWriter.beginArray();
436        jsonWriter.value(true);
437        jsonWriter.value(false);
438        jsonWriter.value(5.0);
439        jsonWriter.nullValue();
440        jsonWriter.beginObject();
441        jsonWriter.name("a").value(6.0);
442        jsonWriter.name("b").value(7.0);
443        jsonWriter.endObject();
444        jsonWriter.beginArray();
445        jsonWriter.value(8.0);
446        jsonWriter.value(9.0);
447        jsonWriter.endArray();
448        jsonWriter.endArray();
449
450        String expected = "[\n"
451                + "   true,\n"
452                + "   false,\n"
453                + "   5.0,\n"
454                + "   null,\n"
455                + "   {\n"
456                + "      \"a\": 6.0,\n"
457                + "      \"b\": 7.0\n"
458                + "   },\n"
459                + "   [\n"
460                + "      8.0,\n"
461                + "      9.0\n"
462                + "   ]\n"
463                + "]";
464        assertEquals(expected, stringWriter.toString());
465    }
466}
467