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.a.rttests;
18  
19  import static org.apache.juneau.TestUtils.*;
20  import static org.apache.juneau.common.utils.IOUtils.*;
21  import static org.junit.jupiter.api.Assertions.*;
22  
23  import org.junit.jupiter.params.*;
24  import org.junit.jupiter.params.provider.*;
25  
26  /**
27   * Tests to ensure the valueOf(String), fromString(String), parse(String), and parseString(String) methods
28   * are used correctly by parsers.
29   */
30  class ObjectsAsStrings_RoundTripTest extends RoundTripTest_Base {
31  
32  	//====================================================================================================
33  	// testBasic
34  	//====================================================================================================
35  
36  	@ParameterizedTest
37  	@MethodSource("testers")
38  	void a01_basic(RoundTrip_Tester t) throws Exception {
39  		var x = new A().init();
40  		x = t.roundTrip(x);
41  		assertBean(x, "a1{f},a2{f},a3{f},a4{f}", "{1},{2},{3},{4}");
42  	}
43  
44  	public static class A {
45  		public A1 a1;
46  		public A2 a2;
47  		public A3 a3;
48  		public A4 a4;
49  
50  		public A init() {
51  			a1 = new A1();
52  			a1.f = "1";
53  			a2 = new A2();
54  			a2.f = "2";
55  			a3 = new A3();
56  			a3.f = "3";
57  			a4 = new A4();
58  			a4.f = "4";
59  			return this;
60  		}
61  	}
62  
63  	public static class A1 {
64  		public String f;
65  		public static A1 fromString(String s) {
66  			var x = new A1();
67  			x.f = s.substring(3);
68  			return x;
69  		}
70  		@Override /* Object */
71  		public String toString() {
72  			return "A1-" + f;
73  		}
74  	}
75  
76  	public static class A2 {
77  		public String f;
78  		public static A2 valueOf(String s) {
79  			var x = new A2();
80  			x.f = s.substring(3);
81  			return x;
82  		}
83  		@Override /* Object */
84  		public String toString() {
85  			return "A2-" + f;
86  		}
87  	}
88  
89  	public static class A3 {
90  		public String f;
91  		public static A3 parse(String s) {
92  			var x = new A3();
93  			x.f = s.substring(3);
94  			return x;
95  		}
96  		@Override /* Object */
97  		public String toString() {
98  			return "A3-" + f;
99  		}
100 	}
101 
102 	public static class A4 {
103 		public String f;
104 		public static A4 parseString(String s) {
105 			var x = new A4();
106 			x.f = s.substring(3);
107 			return x;
108 		}
109 		@Override /* Object */
110 		public String toString() {
111 			return "A4-" + f;
112 		}
113 	}
114 
115 	//====================================================================================================
116 	// testEnumWithOverriddenStringValue
117 	// The B1 enum should serialize as "X1" but the B2 enum should serialize as "X-1".
118 	//====================================================================================================
119 
120 	@ParameterizedTest
121 	@MethodSource("testers")
122 	void a02_enumWithOverriddenStringValue(RoundTrip_Tester t) throws Exception {
123 		var x = new B().init();
124 		if (! t.returnOriginalObject) {
125 			var r = t.getSerializer().serialize(x);
126 			assertTrue(toString(r).contains("X-2"));
127 		}
128 		x = t.roundTrip(x);
129 		assertBean(x, "b1,b2", "X1,X2");
130 	}
131 
132 	public static class B {
133 		public B1 b1;
134 		public B2 b2;
135 
136 		public B init() {
137 			b1 = B1.X1;
138 			b2 = B2.X2;
139 			return this;
140 		}
141 
142 	}
143 
144 	public enum B1 {
145 		X1(1),
146 		X2(2),
147 		X3(3);
148 
149 		@SuppressWarnings("unused")
150 		private int i;
151 		B1(int i) {
152 			this.i = i;
153 		}
154 	}
155 
156 	public enum B2 {
157 		X1(1),
158 		X2(2),
159 		X3(3);
160 
161 		private int i;
162 		B2(int i) {
163 			this.i = i;
164 		}
165 
166 		@Override /* Object */
167 		public String toString() {
168 			return "X-" + i;
169 		}
170 
171 		public static B2 fromString(String s) {
172 			return valueOf("X" + s.substring(2));
173 		}
174 	}
175 
176 	//====================================================================================================
177 	// testMethodOrdering
178 	//====================================================================================================
179 
180 	@ParameterizedTest
181 	@MethodSource("testers")
182 	void a03_ordering(RoundTrip_Tester t) throws Exception {
183 		var x = new C().init();
184 		x = t.roundTrip(x);
185 		assertJson("{c1:{f:'1'},c2:{f:'2'},c3:{f:'3'},c4:{f:'4'}}", x);
186 	}
187 
188 	public static class C {
189 		public C1 c1;
190 		public C2 c2;
191 		public C3 c3;
192 		public C4 c4;
193 
194 		public C init() {
195 			c1 = new C1();
196 			c1.f = "1";
197 			c2 = new C2();
198 			c2.f = "2";
199 			c3 = new C3();
200 			c3.f = "3";
201 			c4 = new C4();
202 			c4.f = "4";
203 			return this;
204 		}
205 	}
206 
207 	public static class C1 {
208 		public String f;
209 		public static C2 valueOf(String s) {
210 			throw new IllegalCallerException("Shouldn't be called!");
211 		}
212 		public static C2 parse(String s) {
213 			throw new IllegalCallerException("Shouldn't be called!");
214 		}
215 		public static C2 parseString(String s) {
216 			throw new IllegalCallerException("Shouldn't be called!");
217 		}
218 		public static C1 fromString(String s) {
219 			var x = new C1();
220 			x.f = s.substring(3);
221 			return x;
222 		}
223 
224 		@Override /* Object */
225 		public String toString() {
226 			return "C1-" + f;
227 		}
228 	}
229 
230 	public static class C2 {
231 		public String f;
232 		public static C2 parse(String s) {
233 			throw new IllegalCallerException("Shouldn't be called!");
234 		}
235 		public static C2 parseString(String s) {
236 			throw new IllegalCallerException("Shouldn't be called!");
237 		}
238 		public static C2 valueOf(String s) {
239 			var x = new C2();
240 			x.f = s.substring(3);
241 			return x;
242 		}
243 		@Override /* Object */
244 		public String toString() {
245 			return "C2-" + f;
246 		}
247 	}
248 
249 	public static class C3 {
250 		public String f;
251 		public static C2 parseString(String s) {
252 			throw new IllegalCallerException("Shouldn't be called!");
253 		}
254 		public static C3 parse(String s) {
255 			var x = new C3();
256 			x.f = s.substring(3);
257 			return x;
258 		}
259 		@Override /* Object */
260 		public String toString() {
261 			return "C3-" + f;
262 		}
263 	}
264 
265 	public static class C4 {
266 		public String f;
267 		public static C4 parseString(String s) {
268 			var x = new C4();
269 			x.f = s.substring(3);
270 			return x;
271 		}
272 		@Override /* Object */
273 		public String toString() {
274 			return "C4" + f;
275 		}
276 	}
277 
278 	//------------------------------------------------------------------------------------------------------------------
279 	// Utility methods.
280 	//------------------------------------------------------------------------------------------------------------------
281 
282 	private static final String toString(Object o) {
283 		if (o == null)
284 			return null;
285 		if (o instanceof String)
286 			return (String)o;
287 		if (o instanceof byte[])
288 			return new String((byte[])o, UTF8);
289 		return o.toString();
290 	}
291 }