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