View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.httppart;
18  
19  import static org.junit.jupiter.api.Assertions.*;
20  
21  import java.util.*;
22  
23  import org.apache.juneau.*;
24  import org.apache.juneau.collections.*;
25  import org.apache.juneau.json.*;
26  import org.apache.juneau.parser.*;
27  import org.apache.juneau.uon.*;
28  import org.junit.jupiter.api.*;
29  
30  @SuppressWarnings("rawtypes")
31  class UonPartParser_Test extends TestBase {
32  
33  	private static UonParserSession p = UonParser.DEFAULT.getSession();
34  	private static BeanSession bs = p;
35  
36  	private static <T> T parse(String input, ClassMeta<T> type) throws SchemaValidationException, ParseException {
37  		return p.parse((HttpPartType)null, (HttpPartSchema)null, input, type);
38  	}
39  
40  	//====================================================================================================
41  	// Basic test
42  	//====================================================================================================
43  	@Test void a01_basic() throws Exception {
44  
45  		// Simple string
46  		// Top level
47  		var t = "a";
48  		assertEquals("a", parse(t, bs.object()));
49  		assertEquals("a", parse(t, bs.string()));
50  		t = "'a'";
51  		assertEquals("a", parse(t, bs.string()));
52  		assertEquals("a", parse(t, bs.object()));
53  		t = " 'a' ";
54  		assertEquals("a", parse(t, bs.string()));
55  
56  		// Simple map
57  		// Top level
58  		t = "(a=b,c=123,d=false,e=true,f=%00)";
59  		var m = parse(t, bs.getClassMeta(Map.class));
60  		assertEquals("b", m.get("a"));
61  		assertTrue(m.get("c") instanceof Number);
62  		assertEquals(123, m.get("c"));
63  		assertTrue(m.get("d") instanceof Boolean);
64  		assertEquals(Boolean.FALSE, m.get("d"));
65  		assertTrue(m.get("e") instanceof Boolean);
66  		assertEquals(Boolean.TRUE, m.get("e"));
67  		assertEquals("%00", m.get("f"));
68  
69  		t = "(a=b,c=123,d=false,e=true,f=null)";
70  		m = parse(t, bs.getClassMeta(Map.class));
71  		assertTrue(m.containsKey("f"));
72  		assertNull(m.get("f"));
73  
74  		// null
75  		// Top level
76  		t = "null";
77  		assertNull(parse(t, bs.object()));
78  
79  		// Empty array
80  		// Top level
81  		t = "@()";
82  		var l = (List)parse(t, bs.object());
83  		assertTrue(l.isEmpty());
84  		t = " @( ) ";
85  		l = parse(t, bs.getClassMeta(List.class));
86  		assertTrue(l.isEmpty());
87  
88  		// Empty 2 dimensional array
89  		t = "@(@())";
90  		l = (List)parse(t, bs.object());
91  		assertEquals(1, l.size());
92  		l = (List)l.get(0);
93  		assertTrue(l.isEmpty());
94  		t = "@(@())";
95  		l = (List)parse(t, bs.getClassMeta(LinkedList.class, List.class));
96  		assertEquals(1, l.size());
97  		l = (List)l.get(0);
98  		assertTrue(l.isEmpty());
99  
100 		// Array containing empty string
101 		// Top level
102 		t = "@('')";
103 		l = (List)parse(t, bs.object());
104 		assertEquals(1, l.size());
105 		assertEquals("", l.get(0));
106 		t = "@('')";
107 		l = (List)parse(t, bs.getClassMeta(List.class, String.class));
108 		assertEquals(1, l.size());
109 		assertEquals("", l.get(0));
110 
111 		// Array containing 3 empty strings
112 		t = "@('','','')";
113 		l = (List)parse(t, bs.object());
114 		assertEquals(3, l.size());
115 		assertEquals("", l.get(0));
116 		assertEquals("", l.get(1));
117 		assertEquals("", l.get(2));
118 		t = "@('','','')";
119 		l = (List)parse(t, bs.getClassMeta(List.class, Object.class));
120 		assertEquals(3, l.size());
121 		assertEquals("", l.get(0));
122 		assertEquals("", l.get(1));
123 		assertEquals("", l.get(2));
124 
125 		// String containing \u0000
126 		// Top level
127 		t = "'\u0000'";
128 		assertEquals("\u0000", parse(t, bs.object()));
129 		t = "'\u0000'";
130 		assertEquals("\u0000", parse(t, bs.string()));
131 		assertEquals("\u0000", parse(t, bs.object()));
132 
133 		// Boolean
134 		// Top level
135 		var b = false;
136 		t = "false";
137 		b = (Boolean)parse(t, bs.object());
138 		assertEquals(Boolean.FALSE, b);
139 		b = parse(t, bs.getClassMeta(Boolean.class));
140 		assertEquals(Boolean.FALSE, b);
141 		t = "false";
142 		b = parse(t, bs.getClassMeta(Boolean.class));
143 		assertEquals(Boolean.FALSE, b);
144 
145 		// Number
146 		// Top level
147 		t = "123";
148 		var i = (Integer)parse(t, bs.object());
149 		assertEquals(123, i.intValue());
150 		i = parse(t, bs.getClassMeta(Integer.class));
151 		assertEquals(123, i.intValue());
152 		var d = parse(t, bs.getClassMeta(Double.class));
153 		assertEquals(123, d.intValue());
154 		var f = parse(t, bs.getClassMeta(Float.class));
155 		assertEquals(123, f.intValue());
156 		t = "123";
157 		i = parse(t, bs.getClassMeta(Integer.class));
158 		assertEquals(123, i.intValue());
159 
160 		// Unencoded chars
161 		// Top level
162 		t = "x;/?:@-_.!*'";
163 		assertEquals("x;/?:@-_.!*'", parse(t, bs.object()));
164 
165 		// Encoded chars
166 		// Top level
167 		t = "x{}|\\^[]`<>#%\"&+";
168 		assertEquals("x{}|\\^[]`<>#%\"&+", parse(t, bs.object()));
169 		t = "x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B";
170 		assertEquals("x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", parse(t, bs.object()));
171 		assertEquals("x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B", parse(t, bs.string()));
172 
173 		// Special chars
174 		// These characters are escaped and not encoded.
175 		// Top level
176 		t = "'x$,()'";
177 		assertEquals("x$,()", parse(t, bs.object()));
178 
179 		// Equals sign
180 		// Gets encoded at top level, and encoded+escaped at 2nd level.
181 		// Top level
182 		t = "'x='";
183 		assertEquals("x=", parse(t, bs.object()));
184 		t = "'x%3D'";
185 		assertEquals("x%3D", parse(t, bs.object()));
186 
187 		// String starting with parenthesis
188 		// Top level
189 		t = "'()'";
190 		assertEquals("()", parse(t, bs.object()));
191 		assertEquals("()", parse(t, bs.string()));
192 
193 		// String starting with $
194 		// Top level
195 		t = "$a";
196 		assertEquals("$a", parse(t, bs.object()));
197 		t = "$a";
198 		assertEquals("$a", parse(t, bs.object()));
199 
200 		// Blank string
201 		// Top level
202 		t = "";
203 		assertEquals("", parse(t, bs.object()));
204 
205 		// Newline character
206 		// Top level
207 		t = "'%0A'";
208 		assertEquals("%0A", parse(t, bs.object()));
209 		t = "'\n'";
210 		assertEquals("\n", parse(t, bs.object()));
211 	}
212 
213 	//====================================================================================================
214 	// Unicode character test
215 	//====================================================================================================
216 	@Test void a02_unicodeChars() throws Exception {
217 		var t = "¢";
218 
219 		// 2-byte UTF-8 character
220 		// Top level
221 		assertEquals("¢", parse(t, bs.object()));
222 		assertEquals("¢", parse(t, bs.string()));
223 		t = "%C2%A2";
224 		assertEquals("%C2%A2", parse(t, bs.object()));
225 		assertEquals("%C2%A2", parse(t, bs.string()));
226 
227 		// 3-byte UTF-8 character
228 		// Top level
229 		t = "€";
230 		assertEquals("€", parse(t, bs.object()));
231 		assertEquals("€", parse(t, bs.string()));
232 		t = "%E2%82%AC";
233 		assertEquals("%E2%82%AC", parse(t, bs.object()));
234 		assertEquals("%E2%82%AC", parse(t, bs.string()));
235 
236 		// 4-byte UTF-8 character
237 		// Top level
238 		t = "𤭢";
239 		assertEquals("𤭢", parse(t, bs.object()));
240 		assertEquals("𤭢", parse(t, bs.string()));
241 		t = "%F0%A4%AD%A2";
242 		assertEquals("%F0%A4%AD%A2", parse(t, bs.object()));
243 		assertEquals("%F0%A4%AD%A2", parse(t, bs.string()));
244 	}
245 
246 	//====================================================================================================
247 	// Test simple bean
248 	//====================================================================================================
249 	@Test void a03_simpleBean() throws Exception {
250 		var s = "(f1=foo,f2=123)";
251 		var t = parse(s, bs.getClassMeta(A.class));
252 		assertEquals("foo", t.f1);
253 		assertEquals(123, t.f2);
254 
255 		s = "('f1'='foo','f2'=123)";
256 		t = parse(s, bs.getClassMeta(A.class));
257 		assertEquals("foo", t.f1);
258 		assertEquals(123, t.f2);
259 	}
260 
261 	public static class A {
262 		public String f1;
263 		public int f2;
264 	}
265 
266 	@Test void a04_parseParameterJsonMap() throws Exception {
267 		var in = "(name='foo bar')";
268 		var r = parse(in, BeanContext.DEFAULT.getClassMeta(JsonMap.class));
269 		assertEquals("{name:'foo bar'}", Json5Serializer.DEFAULT.toString(r));
270 	}
271 }