1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.json;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.junit.bct.BctAssertions.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import java.io.*;
24
25 import org.apache.juneau.*;
26 import org.apache.juneau.collections.*;
27 import org.apache.juneau.parser.*;
28 import org.junit.jupiter.api.*;
29
30 class JsonParser_Test extends TestBase {
31
32 private static final JsonParser p = JsonParser.DEFAULT;
33 private static final JsonParser sp = JsonParser.DEFAULT_STRICT;
34
35
36
37
38 @Test void a01_invalidJson() {
39 assertThrows(ParseException.class, ()->p.parse("{\na:1,\nb:xxx\n}", Object.class));
40 }
41
42 @Test void a02_nonExistentAttribute() throws Exception {
43 var json = "{foo:,bar:}";
44 var m = p.parse(json, JsonMap.class);
45 assertEquals("{foo:null,bar:null}", m.toString());
46 }
47
48 @Test void a03_nonStringAsString() throws Exception {
49 var json = "123";
50 var s = p.parse(json, String.class);
51
52
53 assertThrowsWithMessage(Exception.class, "Did not find quote character", ()->sp.parse("123", String.class));
54
55 assertEquals("123", s);
56
57 json = " 123 ";
58
59 assertThrowsWithMessage(Exception.class, "Did not find quote character", ()->sp.parse(" 123 ", String.class));
60
61 s = p.parse(json, String.class);
62 assertEquals("123", s);
63
64 json = "{\"fa\":123}";
65 assertThrowsWithMessage(Exception.class, "Did not find quote character", ()->sp.parse("{\"fa\":123}", A.class));
66
67 var a = p.parse(json, A.class);
68 assertEquals("123", a.fa);
69
70 json = " { \"fa\" : 123 } ";
71 assertThrowsWithMessage(Exception.class, "Did not find quote character", ()->sp.parse(" { \"fa\" : 123 } ", A.class));
72
73 a = p.parse(json, A.class);
74 assertEquals("123", a.fa);
75
76 assertThrowsWithMessage(Exception.class, "Invalid quote character", ()->sp.parse("'123'", String.class));
77 }
78
79 public static class A {
80 public String fa;
81 }
82
83 @Test void a04_strictMode() {
84 var p2 = sp;
85 assertThrowsWithMessage(Exception.class, "Missing value detected.", ()->p2.parse("{\"foo\":,\"bar\":}", JsonMap.class));
86 assertThrowsWithMessage(Exception.class, "Invalid quote character", ()->p2.parse("{\"foo\":'bar'}", JsonMap.class));
87 assertThrowsWithMessage(Exception.class, "Invalid quote character", ()->p2.parse("{'foo':\"bar\"}", JsonMap.class));
88 assertThrowsWithMessage(Exception.class, "Unquoted attribute detected.", ()->p2.parse("{foo:\"bar\"}", JsonMap.class));
89 assertThrowsWithMessage(Exception.class, "String concatenation detected.", ()->p2.parse("{\"foo\":\"bar\"+\"baz\"}", JsonMap.class));
90 assertThrowsWithMessage(Exception.class, "String concatenation detected.", ()->p2.parse("{\"foo\":\"bar\" + \"baz\"}", JsonMap.class));
91 assertThrowsWithMessage(Exception.class, "Javascript comment detected.", ()->p2.parse("{\"foo\":/*comment*/\"bar\"}", JsonMap.class));
92 }
93
94
95
96
97 @Test void a05_primitivesAsStrings() throws Exception {
98 var p2 = JsonParser.DEFAULT;
99 var s = Json5Serializer.DEFAULT;
100
101 var json = "{f01:'1',f02:'1',f03:'true',f04:'true',f05:'1',f06:'1',f07:'1',f08:'1',f09:'1',f10:'1'}";
102 var b = p2.parse(json, B.class);
103 assertEquals("{f01:1,f02:1,f03:true,f04:true,f05:1.0,f06:1.0,f07:1,f08:1,f09:1,f10:1}", s.toString(b));
104
105 json = "{f01:'',f02:'',f03:'',f04:'',f05:'',f06:'',f07:'',f08:'',f09:'',f10:''}";
106 b = p2.parse(json, B.class);
107 assertEquals("{f01:0,f02:0,f03:false,f04:false,f05:0.0,f06:0.0,f07:0,f08:0,f09:0,f10:0}", s.toString(b));
108 }
109
110 public static class B {
111 public int f01;
112 public Integer f02;
113 public boolean f03;
114 public Boolean f04;
115 public float f05;
116 public Float f06;
117 public long f07;
118 public Long f08;
119 public byte f09;
120 public Byte f10;
121 }
122
123
124
125
126
127 @Test void a06_invalidJsonNumbers() throws Exception {
128 var p1 = JsonParser.DEFAULT;
129 var p2 = JsonParser.DEFAULT_STRICT;
130
131
132 var s = "\"\"";
133 var r = p1.parse(s, Number.class);
134 assertEquals(0, r.intValue());
135 assertTrue(r instanceof Integer);
136 assertThrowsWithMessage(Exception.class, "Invalid JSON number", ()->p2.parse("\"\"", Number.class));
137
138
139 s = "0";
140 r = p1.parse(s, Number.class);
141 assertEquals(0, r.intValue());
142 assertTrue(r instanceof Integer);
143 r = p2.parse(s, Number.class);
144 assertEquals(0, r.intValue());
145 assertTrue(r instanceof Integer);
146
147 s = "-0";
148 r = p1.parse(s, Number.class);
149 assertEquals(0, r.intValue());
150 assertTrue(r instanceof Integer);
151 r = p2.parse(s, Number.class);
152 assertEquals(0, r.intValue());
153 assertTrue(r instanceof Integer);
154
155
156 s = "0123";
157 r = p1.parse(s, Number.class);
158 assertEquals(0123, r.intValue());
159 assertTrue(r instanceof Integer);
160 assertThrowsWithMessage(Exception.class, "Invalid JSON number", ()->p2.parse("0123", Number.class));
161 s = "-0123";
162 r = p1.parse(s, Number.class);
163 assertEquals(-0123, r.intValue());
164 assertTrue(r instanceof Integer);
165 assertThrowsWithMessage(Exception.class, "Invalid JSON number", ()->p2.parse("-0123", Number.class));
166
167
168 s = "0x123";
169 r = p1.parse(s, Number.class);
170 assertEquals(0x123, r.intValue());
171 assertTrue(r instanceof Integer);
172 assertThrowsWithMessage(Exception.class, "Invalid JSON number", ()->p2.parse("0x123", Number.class));
173 s = "-0x123";
174 r = p1.parse(s, Number.class);
175 assertEquals(-0x123, r.intValue());
176 assertTrue(r instanceof Integer);
177 assertThrowsWithMessage(Exception.class, "Invalid JSON number", ()->p2.parse("-0x123", Number.class));
178 }
179
180
181
182
183
184 @Test void a07_unquotedStrings() throws Exception {
185 var p1 = JsonParser.DEFAULT;
186 var p2 = JsonParser.DEFAULT_STRICT;
187
188 var s = "foobar";
189 var c = p1.parse(s, C.class);
190 assertEquals("f=foobar", c.toString());
191
192 assertThrows(ParseException.class, ()->p2.parse(s, C.class));
193 }
194
195 public static class C {
196 String f;
197 public static C valueOf(String s) {
198 var c = new C();
199 c.f = s;
200 return c;
201 }
202 @Override
203 public String toString() {
204 return "f="+f;
205 }
206 }
207
208
209
210
211
212 @Test void a08_streamsAutoClose() throws Exception {
213 var p2 = JsonParser.DEFAULT.copy().autoCloseStreams().build();
214 var r = reader("{foo:'bar'}{baz:'qux'}");
215
216 var x = p2.parse(r, JsonMap.class);
217 assertBean(x, "foo", "bar");
218 assertThrowsWithMessage(Exception.class, "Reader is closed", ()->p2.parse(r, JsonMap.class));
219 }
220
221
222
223
224
225 @Test void a09_multipleObjectsInStream() throws Exception {
226 var p2 = JsonParser.create().unbuffered().build();
227 var r = reader("{foo:'bar'}{baz:'qux'}");
228
229 var x = (Object)p2.parse(r, JsonMap.class);
230 assertBean(x, "foo", "bar");
231 x = p2.parse(r, JsonMap.class);
232 assertBean(x, "baz", "qux");
233
234 r = reader("[123][456]");
235 x = p2.parse(r, JsonList.class);
236 assertList(x, "123");
237 x = p2.parse(r, JsonList.class);
238 assertList(x, "456");
239 }
240
241 private static Reader reader(String in) {
242 return new CloseableStringReader(in);
243 }
244 }