1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.html;
18
19 import static org.apache.juneau.commons.utils.CollectionUtils.*;
20 import static org.apache.juneau.html.annotation.HtmlFormat.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import java.util.*;
24
25 import org.apache.juneau.*;
26 import org.apache.juneau.annotation.*;
27 import org.apache.juneau.collections.*;
28 import org.apache.juneau.html.annotation.*;
29 import org.apache.juneau.testutils.pojos.*;
30 import org.junit.jupiter.api.*;
31
32 @SuppressWarnings("serial")
33 class Html_Test extends TestBase {
34
35
36
37
38 @Test void a01_testTables1() throws Exception {
39 var s = HtmlSerializer.DEFAULT_SQ;
40 var t = a(new A1(), new A1());
41 var html = s.serialize(t);
42 assertEquals("<table _type='array'><tr><th>f1</th></tr><tr><td>f1</td></tr><tr><td>f1</td></tr></table>", html);
43 }
44
45 public static class A1 {
46 public String f1 = "f1";
47 }
48
49
50
51
52 @Test void a02_testAnchorTextOptions() throws Exception {
53 var s = HtmlSerializer.create().sq().addKeyValueTableHeaders().uriResolution(UriResolution.NONE);
54 var t = new TestURI();
55
56 s.uriAnchorText(AnchorText.TO_STRING);
57 var r = strip(s.build().serialize(t));
58 var expected = """
59
60 [f0]=<a href='f0/x0'>f0/x0</a>
61 [f1]=<a href='f1/x1'>f1/x1</a>
62 [f2]=<a href='/f2/x2'>/f2/x2</a>
63 [f3]=<a href='http:
64 [f4]=<a href='f4/x4'>f4/x4</a>
65 [f5]=<a href='/f5/x5'>/f5/x5</a>
66 [f6]=<a href='http:
67 [f7]=<a href='http:
68 [f8]=<a href='f8/x8'>f8/x8</a>
69 [f9]=<a href='f9/x9'>f9/x9</a>
70 [fa]=<a href='http:
71 [fb]=<a href='http:
72 [fc]=<a href='http:
73 [fd]=<a href='http:
74 [fe]=<a href='http:
75 assertEquals(expected, r);
76
77 s.uriAnchorText(AnchorText.URI);
78 r = strip(s.build().serialize(t));
79 expected = """
80
81 [f0]=<a href='f0/x0'>f0/x0</a>
82 [f1]=<a href='f1/x1'>f1/x1</a>
83 [f2]=<a href='/f2/x2'>/f2/x2</a>
84 [f3]=<a href='http:
85 [f4]=<a href='f4/x4'>f4/x4</a>
86 [f5]=<a href='/f5/x5'>/f5/x5</a>
87 [f6]=<a href='http:
88 [f7]=<a href='http:
89 [f8]=<a href='f8/x8'>f8/x8</a>
90 [f9]=<a href='f9/x9'>f9/x9</a>
91 [fa]=<a href='http:
92 [fb]=<a href='http:
93 [fc]=<a href='http:
94 [fd]=<a href='http:
95 [fe]=<a href='http:
96 assertEquals(expected, r);
97
98 s.uriAnchorText(AnchorText.LAST_TOKEN);
99 r = strip(s.build().serialize(t));
100 expected = """
101
102 [f0]=<a href='f0/x0'>x0</a>
103 [f1]=<a href='f1/x1'>x1</a>
104 [f2]=<a href='/f2/x2'>x2</a>
105 [f3]=<a href='http:
106 [f4]=<a href='f4/x4'>x4</a>
107 [f5]=<a href='/f5/x5'>x5</a>
108 [f6]=<a href='http:
109 [f7]=<a href='http:
110 [f8]=<a href='f8/x8'>x8</a>
111 [f9]=<a href='f9/x9'>x9</a>
112 [fa]=<a href='http:
113 [fb]=<a href='http:
114 [fc]=<a href='http:
115 [fd]=<a href='http:
116 [fe]=<a href='http:
117 assertEquals(expected, r);
118
119 s.uriAnchorText(AnchorText.URI_ANCHOR);
120 r = strip(s.build().serialize(t));
121 expected = """
122
123 [f0]=<a href='f0/x0'>f0/x0</a>
124 [f1]=<a href='f1/x1'>f1/x1</a>
125 [f2]=<a href='/f2/x2'>/f2/x2</a>
126 [f3]=<a href='http:
127 [f4]=<a href='f4/x4'>f4/x4</a>
128 [f5]=<a href='/f5/x5'>/f5/x5</a>
129 [f6]=<a href='http:
130 [f7]=<a href='http:
131 [f8]=<a href='f8/x8'>f8/x8</a>
132 [f9]=<a href='f9/x9'>f9/x9</a>
133 [fa]=<a href='http:
134 [fb]=<a href='http:
135 [fc]=<a href='http:
136 [fd]=<a href='http:
137 [fe]=<a href='http:
138 assertEquals(expected, r);
139
140 s.labelParameter("label2");
141 r = strip(s.build().serialize(t));
142 expected = """
143
144 [f0]=<a href='f0/x0'>f0/x0</a>
145 [f1]=<a href='f1/x1'>f1/x1</a>
146 [f2]=<a href='/f2/x2'>/f2/x2</a>
147 [f3]=<a href='http:
148 [f4]=<a href='f4/x4'>f4/x4</a>
149 [f5]=<a href='/f5/x5'>/f5/x5</a>
150 [f6]=<a href='http:
151 [f7]=<a href='http:
152 [f8]=<a href='f8/x8'>f8/x8</a>
153 [f9]=<a href='f9/x9'>f9/x9</a>
154 [fa]=<a href='http:
155 [fb]=<a href='http:
156 [fc]=<a href='http:
157 [fd]=<a href='http:
158 [fe]=<a href='http:
159 assertEquals(expected, r);
160
161 s.disableDetectLinksInStrings();
162 r = strip(s.build().serialize(t));
163 expected = """
164
165 [f0]=<a href='f0/x0'>f0/x0</a>
166 [f1]=<a href='f1/x1'>f1/x1</a>
167 [f2]=<a href='/f2/x2'>/f2/x2</a>
168 [f3]=<a href='http:
169 [f4]=<a href='f4/x4'>f4/x4</a>
170 [f5]=<a href='/f5/x5'>/f5/x5</a>
171 [f6]=<a href='http:
172 [f7]=<a href='http:
173 [f8]=<a href='f8/x8'>f8/x8</a>
174 [f9]=<a href='f9/x9'>f9/x9</a>
175 [fa]=http:
176 [fb]=http:
177 [fc]=http:
178 [fd]=http:
179 [fe]=http:
180 assertEquals(expected, r);
181
182 s.disableDetectLinksInStrings(false);
183 s.disableDetectLabelParameters();
184 r = strip(s.build().serialize(t));
185 expected = """
186
187 [f0]=<a href='f0/x0'>f0/x0</a>
188 [f1]=<a href='f1/x1'>f1/x1</a>
189 [f2]=<a href='/f2/x2'>/f2/x2</a>
190 [f3]=<a href='http:
191 [f4]=<a href='f4/x4'>f4/x4</a>
192 [f5]=<a href='/f5/x5'>/f5/x5</a>
193 [f6]=<a href='http:
194 [f7]=<a href='http:
195 [f8]=<a href='f8/x8'>f8/x8</a>
196 [f9]=<a href='f9/x9'>f9/x9</a>
197 [fa]=<a href='http:
198 [fb]=<a href='http:
199 [fc]=<a href='http:
200 [fd]=<a href='http:
201 [fe]=<a href='http:
202 assertEquals(expected, r);
203 }
204
205 private static String strip(String html) {
206 return html
207 .replace("<table><tr><th>key</th><th>value</th></tr>", "")
208 .replace("</table>", "")
209 .replace("<tr><td>", "\n[")
210 .replace("</td><td>", "]=")
211 .replace("</td></tr>", "");
212 }
213
214
215
216
217 @Test void b01_testHtmlAnnotationAsPlainText() throws Exception {
218 var s = HtmlSerializer.create().sq().addKeyValueTableHeaders().build();
219
220 var o = new B1();
221 var r = s.serialize(o);
222 assertEquals("<test>", r);
223
224 var o2 = new B2();
225 r = s.serialize(o2);
226 assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f1</td><td><f1></td></tr></table>", r);
227 }
228
229 @Html(format=PLAIN_TEXT)
230 public static class B1 {
231 public String f1 = "<f1>";
232 @Override
233 public String toString() {
234 return "<test>";
235 }
236 }
237
238 public static class B2 {
239 @Html(format=PLAIN_TEXT)
240 public String f1 = "<f1>";
241 }
242
243 @Test void b02_testHtmlAnnotationAsPlainText_usingConfig() throws Exception {
244 var s = HtmlSerializer.create().sq().addKeyValueTableHeaders().applyAnnotations(B3Config.class).build();
245
246 var o = new B3();
247 var r = s.serialize(o);
248 assertEquals("<test>", r);
249
250 var o2 = new B4();
251 r = s.serialize(o2);
252 assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f1</td><td><f1></td></tr></table>", r);
253 }
254
255 @Html(on="B3", format=PLAIN_TEXT)
256 @Html(on="B4.f1", format=PLAIN_TEXT)
257 private static class B3Config {}
258
259 public static class B3 {
260 public String f1 = "<f1>";
261 @Override
262 public String toString() {
263 return "<test>";
264 }
265 }
266
267 public static class B4 {
268 public String f1 = "<f1>";
269 }
270
271
272
273
274 @Test void c01_testHtmlAnnotationAsXml() throws Exception {
275 var s = HtmlSerializer.create().sq().addKeyValueTableHeaders().build();
276
277 var o = new C1();
278 var r = s.serialize(o);
279 assertEquals("<object><f1><f1></f1></object>", r);
280
281 var o2 = new C2();
282 r = s.serialize(o2);
283 assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f1</td><td><f1></td></tr></table>", r);
284 }
285
286 @Html(format=XML)
287 public static class C1 {
288 public String f1 = "<f1>";
289 }
290
291 public static class C2 {
292 @Html(format=XML)
293 public String f1 = "<f1>";
294 }
295
296 @Test void c02_testHtmlAnnotationAsXml_usingConfig() throws Exception {
297 var s = HtmlSerializer.create().sq().addKeyValueTableHeaders().applyAnnotations(C3Config.class).build();
298
299 var o = new C3();
300 var r = s.serialize(o);
301 assertEquals("<object><f1><f1></f1></object>", r);
302
303 var o2 = new C4();
304 r = s.serialize(o2);
305 assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f1</td><td><f1></td></tr></table>", r);
306 }
307
308 @Html(on="C3,C4.f1",format=XML)
309 private static class C3Config {}
310
311 public static class C3 {
312 public String f1 = "<f1>";
313 }
314
315 public static class C4 {
316 public String f1 = "<f1>";
317 }
318
319
320
321
322 @Test void d01_testNoTableHeaders() throws Exception {
323 var s = HtmlSerializer.DEFAULT_SQ;
324
325 var m = new MyMap();
326 m.put("foo", "bar");
327 var o = JsonList.of(m);
328 var r = s.serialize(o);
329 assertEquals("<ul><li><table><tr><td>foo</td><td>bar</td></tr></table></li></ul>", r);
330 }
331
332 @Html(noTables=true, noTableHeaders=true)
333 public static class MyMap extends LinkedHashMap<String,String> {}
334
335 @Test void d02_testNoTableHeaders_usingConfig() throws Exception {
336 var s = HtmlSerializer.DEFAULT_SQ.copy().applyAnnotations(MyMap2Config.class).build();
337
338 var m = new MyMap2();
339 m.put("foo", "bar");
340 var o = JsonList.of(m);
341 var r = s.serialize(o);
342 assertEquals("<ul><li><table><tr><td>foo</td><td>bar</td></tr></table></li></ul>", r);
343 }
344
345 @Html(on="org.apache.juneau.html.Html_Test$MyMap2", noTables=true, noTableHeaders=true)
346 private static class MyMap2Config {}
347
348 public static class MyMap2 extends LinkedHashMap<String,String> {}
349
350
351
352
353 @Test void d03_testNoTableHeadersOnBeans() throws Exception {
354 var s = HtmlSerializer.DEFAULT_SQ;
355
356 var b = new MyBean();
357 var o = JsonList.of(b,b);
358 var r = s.serialize(o);
359 assertEquals("<table _type='array'><tr><td>1</td><td>2</td><td>3</td></tr><tr><td>1</td><td>2</td><td>3</td></tr></table>", r);
360 }
361
362 @Html(noTableHeaders=true)
363 public static class MyBean {
364 public int a=1,b=2,c=3;
365 }
366
367 @Test void d04_testNoTableHeadersOnBeans_usingConfig() throws Exception {
368 var s = HtmlSerializer.DEFAULT_SQ.copy().applyAnnotations(MyBean2Config.class).build();
369
370 var b = new MyBean();
371 var o = JsonList.of(b,b);
372 var r = s.serialize(o);
373 assertEquals("<table _type='array'><tr><td>1</td><td>2</td><td>3</td></tr><tr><td>1</td><td>2</td><td>3</td></tr></table>", r);
374 }
375
376 @Html(on="MyBean2", noTableHeaders=true)
377 private static class MyBean2Config {}
378
379 public static class MyBean2 {
380 public int a=1,b=2,c=3;
381 }
382
383 @Test void d05_testNoTableHeadersOnBeans_usingConcreteAnnotation() throws Exception {
384 var s = HtmlSerializer.DEFAULT_SQ.copy().annotations(HtmlAnnotation.create("MyBean2").noTables(true).build()).build();
385
386 var b = new MyBean();
387 var o = JsonList.of(b,b);
388 var r = s.serialize(o);
389 assertEquals("<table _type='array'><tr><td>1</td><td>2</td><td>3</td></tr><tr><td>1</td><td>2</td><td>3</td></tr></table>", r);
390 }
391
392
393
394
395
396 @Bean(p="f3,f2,f1")
397 public static class E {
398 public Integer f1, f2, f3;
399
400 public E(Integer f1, Integer f2, Integer f3) {
401 this.f1 = f1;
402 this.f2 = f2;
403 this.f3 = f3;
404 }
405 }
406
407 @Test void e01_collectionOfBeansWithBpi() {
408 E[] ee = a(
409 new E(null, 2, 3),
410 new E(4, 5, 6)
411 );
412 assertEquals("<table _type='array'><tr><th>f3</th><th>f2</th><th>f1</th></tr><tr><td>3</td><td>2</td><td><null/></td></tr><tr><td>6</td><td>5</td><td>4</td></tr></table>", HtmlSerializer.DEFAULT_SQ.toString(ee));
413 assertEquals("<table _type='array'><tr><th>f3</th><th>f2</th><th>f1</th></tr><tr><td>3</td><td>2</td><td><null/></td></tr><tr><td>6</td><td>5</td><td>4</td></tr></table>", HtmlSerializer.DEFAULT_SQ.toString(l(ee)));
414
415 ee = a(
416 new E(null, null, null),
417 new E(null, null, null)
418 );
419 assertEquals("<table _type='array'><tr><th>f3</th><th>f2</th><th>f1</th></tr><tr><td><null/></td><td><null/></td><td><null/></td></tr><tr><td><null/></td><td><null/></td><td><null/></td></tr></table>", HtmlSerializer.DEFAULT_SQ.toString(ee));
420 }
421
422
423
424
425
426 @Test void f01_htmlStyle() throws Exception {
427 var s = HtmlSerializer.DEFAULT_SQ;
428 F[] ff = {
429 new F("foo", "bar"),
430 new F("baz", "qux")
431 };
432 var html = s.serialize(ff);
433 assertTrue(html.contains("style='white-space:normal'"));
434 assertTrue(html.contains("style='min-width:200px'"));
435 }
436
437 public static class F {
438 @Html(style="white-space:normal")
439 public String f1;
440
441 @Html(style="min-width:200px")
442 public String f2;
443
444 public F(String f1, String f2) {
445 this.f1 = f1;
446 this.f2 = f2;
447 }
448 }
449 }