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;
18  
19  import static org.apache.juneau.commons.utils.CollectionUtils.*;
20  import static org.apache.juneau.commons.utils.StringUtils.*;
21  import static org.apache.juneau.commons.utils.Utils.*;
22  import static org.apache.juneau.junit.bct.BctAssertions.*;
23  import static org.junit.jupiter.api.Assertions.*;
24  
25  import java.util.*;
26  import java.util.function.*;
27  
28  import org.apache.juneau.commons.function.*;
29  import org.apache.juneau.html.*;
30  import org.apache.juneau.json.*;
31  import org.apache.juneau.msgpack.*;
32  import org.apache.juneau.serializer.*;
33  import org.apache.juneau.uon.*;
34  import org.apache.juneau.urlencoding.*;
35  import org.apache.juneau.xml.*;
36  
37  /**
38   * Represents the input to a ComboTest.
39   * @param <T>
40   */
41  public class ComboSerialize_Tester<T> {
42  
43  	public static <T> Builder<T> create(int index, String label, Supplier<T> in) {
44  		return new Builder<>(index, label, in);
45  	}
46  
47  	public static class Builder<T> {
48  		private int index;
49  		private String label;
50  		private Supplier<T> in;
51  		private String exceptionMsg;
52  		private Predicate<String> skipTest = x -> false;
53  		private List<Class<?>> swaps = list();
54  		private Map<String,String> expected = map();
55  		private List<Tuple2<Class<?>,Consumer<?>>> applies = list();
56  		private Consumer<Serializer.Builder> serializerApply = x -> {};
57  
58  		public Builder(int index, String label, T in) {
59  			this.index = index;
60  			this.label = label;
61  			this.in = () -> in;
62  		}
63  
64  		public Builder(int index, String label, Supplier<T> in) {
65  			this.index = index;
66  			this.label = label;
67  			this.in = in;
68  		}
69  
70  		public Builder<T> beanContext(Consumer<BeanContext.Builder> c) { apply(BeanContext.Builder.class, c); return this; }
71  
72  		public <T2> Builder<T> apply(Class<T2> t, Consumer<T2> c) { applies.add(Tuple2.of(t, c)); return this; }
73  
74  		public Builder<T> exceptionMsg(String v) { exceptionMsg = v; return this; }
75  
76  		public Builder<T> skipTest(Predicate<String> v) { skipTest = v; return this; }
77  
78  		public Builder<T> swaps(Class<?>...c) { swaps.addAll(l(c)); return this; }
79  
80  		public Builder<T> serializerApply(Consumer<Serializer.Builder> v) { serializerApply = v; return this; }
81  
82  		public Builder<T> json(String value) { expected.put("json", value); return this; }
83  		public Builder<T> jsonT(String value) { expected.put("jsonT", value); return this; }
84  		public Builder<T> jsonR(String value) { expected.put("jsonR", value); return this; }
85  		public Builder<T> xml(String value) { expected.put("xml", value); return this; }
86  		public Builder<T> xmlT(String value) { expected.put("xmlT", value); return this; }
87  		public Builder<T> xmlR(String value) { expected.put("xmlR", value); return this; }
88  		public Builder<T> xmlNs(String value) { expected.put("xmlNs", value); return this; }
89  		public Builder<T> html(String value) { expected.put("html", value); return this; }
90  		public Builder<T> htmlT(String value) { expected.put("htmlT", value); return this; }
91  		public Builder<T> htmlR(String value) { expected.put("htmlR", value); return this; }
92  		public Builder<T> uon(String value) { expected.put("uon", value); return this; }
93  		public Builder<T> uonT(String value) { expected.put("uonT", value); return this; }
94  		public Builder<T> uonR(String value) { expected.put("uonR", value); return this; }
95  		public Builder<T> urlEnc(String value) { expected.put("urlEnc", value); return this; }
96  		public Builder<T> urlEncT(String value) { expected.put("urlEncT", value); return this; }
97  		public Builder<T> urlEncR(String value) { expected.put("urlEncR", value); return this; }
98  		public Builder<T> msgPack(String value) { expected.put("msgPack", value); return this; }
99  		public Builder<T> msgPackT(String value) { expected.put("msgPackT", value); return this; }
100 		public Builder<T> rdfXml(String value) { expected.put("rdfXml", value); return this; }
101 		public Builder<T> rdfXmlT(String value) { expected.put("rdfXmlT", value); return this; }
102 		public Builder<T> rdfXmlR(String value) { expected.put("rdfXmlR", value); return this; }
103 
104 		public ComboSerialize_Tester<T> build() {
105 			return new ComboSerialize_Tester<>(this);
106 		}
107 	}
108 
109 	private final String label;
110 	private final Supplier<T> in;
111 	private final String exceptionMsg;
112 	private final Predicate<String> skipTest;
113 	private final Map<String,String> expected;
114 	private final Map<String,Serializer> serializers = map();
115 
116 	private ComboSerialize_Tester(Builder<T> b) {
117 		label = "[" + b.index + "] " + b.label;
118 		in = b.in;
119 		expected = b.expected;
120 		skipTest = b.skipTest;
121 		exceptionMsg = b.exceptionMsg;
122 
123 		serializers.put("json", create(b, Json5Serializer.DEFAULT.copy().addBeanTypes().addRootType()));
124 		serializers.put("jsonT", create(b, Json5Serializer.create().json5().typePropertyName("t").addBeanTypes().addRootType()));
125 		serializers.put("jsonR", create(b, Json5Serializer.DEFAULT_READABLE.copy().addBeanTypes().addRootType()));
126 		serializers.put("xml", create(b, XmlSerializer.DEFAULT_SQ.copy().addBeanTypes().addRootType()));
127 		serializers.put("xmlT", create(b, XmlSerializer.create().sq().typePropertyName("t").addBeanTypes().addRootType()));
128 		serializers.put("xmlR", create(b, XmlSerializer.DEFAULT_SQ_READABLE.copy().addBeanTypes().addRootType()));
129 		serializers.put("xmlNs", create(b, XmlSerializer.DEFAULT_NS_SQ.copy().addBeanTypes().addRootType()));
130 		serializers.put("html", create(b, HtmlSerializer.DEFAULT_SQ.copy().addBeanTypes().addRootType()));
131 		serializers.put("htmlT", create(b, HtmlSerializer.create().sq().typePropertyName("t").addBeanTypes().addRootType()));
132 		serializers.put("htmlR", create(b, HtmlSerializer.DEFAULT_SQ_READABLE.copy().addBeanTypes().addRootType()));
133 		serializers.put("uon", create(b, UonSerializer.DEFAULT.copy().addBeanTypes().addRootType()));
134 		serializers.put("uonT", create(b, UonSerializer.create().typePropertyName("t").addBeanTypes().addRootType()));
135 		serializers.put("uonR", create(b, UonSerializer.DEFAULT_READABLE.copy().addBeanTypes().addRootType()));
136 		serializers.put("urlEnc", create(b, UrlEncodingSerializer.DEFAULT.copy().addBeanTypes().addRootType()));
137 		serializers.put("urlEncT", create(b, UrlEncodingSerializer.create().typePropertyName("t").addBeanTypes().addRootType()));
138 		serializers.put("urlEncR", create(b, UrlEncodingSerializer.DEFAULT_READABLE.copy().addBeanTypes().addRootType()));
139 		serializers.put("msgPack", create(b, MsgPackSerializer.create().addBeanTypes().addRootType()));
140 		serializers.put("msgPackT", create(b, MsgPackSerializer.create().typePropertyName("t").addBeanTypes().addRootType()));
141 	}
142 
143 	private Serializer create(Builder<?> tb, Serializer.Builder sb) {
144 		tb.serializerApply.accept(sb);
145 		sb.swaps(tb.swaps);
146 		tb.applies.forEach(x -> {
147 			if (x.getA().equals(BeanContext.Builder.class))
148 				sb.beanContext((Consumer<BeanContext.Builder>) x.getB());
149 			else if (x.getA().isInstance(sb))
150 				sb.asSubtype(Serializer.Builder.class).ifPresent((Consumer<Serializer.Builder>) x.getB());
151 		});
152 		return sb.build();
153 	}
154 
155 	private boolean isSkipped(String testName, String expected) {
156 		return "SKIP".equals(expected) || skipTest.test(testName);
157 	}
158 
159 	public void testSerialize(String testName) throws Exception {
160 		var s = serializers.get(testName);
161 		var exp = expected.get(testName);
162 		try {
163 			if (isSkipped(testName + "-serialize", exp)) return;
164 
165 			var r = s.serializeToString(in.get());
166 
167 			// Specifying "xxx" in the expected results will spit out what we should populate the field with.
168 			if (eq(exp, "xxx")) {
169 				System.out.println(getClass().getName() + ": " + label + "/" + testName + "=\n" + r.replaceAll("\n", "\\\\n").replaceAll("\t", "\\\\t")); // NOT DEBUG
170 				System.out.println(r);
171 				if (s instanceof MsgPackSerializer) {
172 					System.out.println("decoded=["+new String(fromHex(r))+"]");
173 				}
174 			}
175 
176 			assertEquals(exp, r, fs("{0}/{1} serialize-normal failed.", label, testName));
177 		} catch (AssertionError e) {
178 			if (exceptionMsg == null)
179 				throw e;
180 			assertContains(exceptionMsg, e.getMessage());
181 		} catch (Exception e) {
182 			if (exceptionMsg == null)
183 				throw new BasicAssertionError(e, "{0}/{1} failed.  exception={2}", label, testName, e.getLocalizedMessage());
184 			assertContains(exceptionMsg, e.getMessage());
185 		}
186 	}
187 
188 	@Override
189 	public String toString() {
190 		return "ComboSerializeTester: " + label;
191 	}
192 }