001package org.apache.maven.doxia.sink.impl;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.StringWriter;
023import java.io.Writer;
024
025import javax.swing.text.html.HTML.Attribute;
026
027import junit.framework.TestCase;
028
029import org.apache.maven.doxia.markup.Markup;
030import org.apache.maven.doxia.sink.Sink;
031import org.apache.maven.doxia.sink.SinkEventAttributes;
032import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
033import org.apache.maven.doxia.sink.impl.XhtmlBaseSink;
034
035/**
036 * Test for XhtmlBaseSink.
037 *
038 * @author ltheussl
039 * @version $Id$
040 * @since 1.1
041 */
042public class XhtmlBaseSinkTest
043    extends TestCase
044{
045    protected static final String LS = Markup.EOL;
046    private final SinkEventAttributes attributes = SinkEventAttributeSet.BOLD;
047    private XhtmlBaseSink sink;
048    private Writer writer;
049
050    /**
051     * Set up the writer.
052     *
053     * @throws java.lang.Exception if any.
054     */
055    @Override
056    protected void setUp()
057            throws Exception
058    {
059        super.setUp();
060        writer =  new StringWriter();
061    }
062
063    /** @throws Exception */
064    public void testSpaceAfterClosingTag()
065        throws Exception
066    {
067        // DOXIA-189
068        try
069        {
070            sink = new XhtmlBaseSink( writer );
071
072            sink.paragraph();
073            sink.text( "There should be no space before the " );
074            sink.italic();
075            sink.text( "period" );
076            sink.italic_();
077            sink.text( "." );
078            sink.paragraph_();
079        }
080        finally
081        {
082            if ( sink != null )
083            {
084                sink.close();
085            }
086        }
087
088        String actual = writer.toString();
089        String expected = "<p>There should be no space before the <i>period</i>.</p>";
090
091        assertEquals( expected, actual );
092    }
093
094    /**
095     * @throws Exception if any
096     */
097    public void testNestedTables()
098        throws Exception
099    {
100        // DOXIA-177
101        try
102        {
103            sink = new XhtmlBaseSink( writer );
104
105            sink.table();
106            sink.tableRows( new int[] { Sink.JUSTIFY_CENTER }, false );
107            sink.tableRow();
108            sink.tableCell();
109            sink.text( "cell11" );
110            sink.tableCell_();
111            sink.tableCell();
112            sink.text( "cell12" );
113            sink.tableCell_();
114            sink.tableRow_();
115
116            sink.tableRow();
117            sink.tableCell();
118            sink.table( SinkEventAttributeSet.LEFT );
119            sink.tableRows( new int[] { Sink.JUSTIFY_LEFT }, false );
120            sink.tableRow();
121            sink.tableCell();
122            sink.text( "nestedTable1Cell11" );
123            sink.tableCell_();
124            sink.tableCell();
125            sink.text( "nestedTable1Cell12" );
126            sink.tableCell_();
127            sink.tableRow_();
128            sink.tableRow();
129            sink.tableCell();
130
131            sink.table( SinkEventAttributeSet.RIGHT );
132            sink.tableRows( new int[] { Sink.JUSTIFY_RIGHT }, false );
133            sink.tableRow();
134            sink.tableCell();
135            sink.text( "nestedTable2Cell11" );
136            sink.tableCell_();
137            sink.tableCell();
138            sink.text( "nestedTable2Cell12" );
139            sink.tableCell_();
140            sink.tableRow_();
141            sink.tableRow();
142            sink.tableCell();
143            sink.text( "nestedTable2Cell21" );
144            sink.tableCell_();
145            sink.tableCell();
146            sink.text( "nestedTable2Cell22" );
147            sink.tableCell_();
148            sink.tableRow_();
149            sink.tableRows_();
150            sink.tableCaption();
151            sink.text( "caption3" );
152            sink.tableCaption_();
153            sink.table_();
154
155            sink.tableCell_();
156            sink.tableCell();
157            sink.text( "nestedTable1Cell22" );
158            sink.tableCell_();
159            sink.tableRow_();
160            sink.tableRows_();
161            sink.tableCaption();
162            sink.text( "caption2" );
163            sink.tableCaption_();
164            sink.table_();
165
166            sink.tableCell_();
167            sink.tableCell();
168            sink.text( "cell22" );
169            sink.tableCell_();
170            sink.tableRow_();
171            sink.tableRows_();
172            sink.tableCaption();
173            sink.text( "caption1" );
174            sink.tableCaption_();
175            sink.table_();
176        }
177        finally
178        {
179            sink.close();
180        }
181
182        String actual = writer.toString();
183        assertTrue( actual.indexOf( "<table align=\"center\" border=\"0\" class=\"bodyTable\">"
184            + "<caption>caption1</caption>" ) != 1 );
185        assertTrue( actual.indexOf( "<table border=\"0\" class=\"bodyTable\" align=\"left\">"
186            + "<caption>caption2</caption>" ) != 1 );
187        assertTrue( actual.indexOf( "<table align=\"center\" border=\"0\" class=\"bodyTable\">"
188            + "<caption>caption3</caption>" ) != 1 );
189
190        assertTrue( actual.indexOf( "<td align=\"center\">cell11</td>" ) != 1 );
191        assertTrue( actual.indexOf( "<td align=\"left\">nestedTable1Cell11</td>" ) != 1 );
192        assertTrue( actual.indexOf( "<td align=\"right\">nestedTable2Cell11</td>" ) != 1 );
193        assertTrue( actual.indexOf( "<td align=\"left\">nestedTable1Cell22</td>" ) != 1 );
194        assertTrue( actual.indexOf( "<td align=\"center\">cell22</td>" ) != 1 );
195    }
196
197    /**
198     * Test of section method, of class XhtmlBaseSink.
199     */
200    public void testSection()
201    {
202        final int level = XhtmlBaseSink.SECTION_LEVEL_1;
203
204        try
205        {
206            sink = new XhtmlBaseSink( writer );
207
208            sink.section( level, attributes );
209            sink.sectionTitle( level, attributes );
210            sink.sectionTitle_( level );
211            sink.section_( level );
212        }
213        finally
214        {
215            sink.close();
216        }
217
218        assertEquals( "<div class=\"section\" style=\"bold\">" + LS + "<h2 style=\"bold\"></h2></div>", writer.toString() );
219    }
220
221    /**
222     * Test of section method, of class XhtmlBaseSink.
223     */
224    public void testSectionAttributes()
225    {
226        final int level = XhtmlBaseSink.SECTION_LEVEL_1;
227        final SinkEventAttributeSet set = new SinkEventAttributeSet(
228            new String[] {"name", "section name", "class", "foo", "id", "bar"} );
229
230        try
231        {
232            sink = new XhtmlBaseSink( writer );
233
234            sink.section( level, set );
235            sink.sectionTitle( level, null );
236            sink.sectionTitle_( level );
237            sink.section_( level );
238        }
239        finally
240        {
241            sink.close();
242        }
243
244        assertEquals( "<div class=\"foo\" id=\"bar\">" + LS + "<h2></h2></div>", writer.toString() );
245    }
246
247    /**
248     * Test of section1 method, of class XhtmlBaseSink.
249     */
250    public void testSection1()
251    {
252
253        try
254        {
255            sink = new XhtmlBaseSink( writer );
256
257            sink.section1();
258            sink.sectionTitle1();
259            sink.sectionTitle1_();
260            sink.section1_();
261        }
262        finally
263        {
264            sink.close();
265        }
266
267        assertEquals( "<div class=\"section\">" + LS + "<h2></h2></div>", writer.toString() );
268    }
269
270    /**
271     * Test of section2 method, of class XhtmlBaseSink.
272     */
273    public void testSection2()
274    {
275
276        try
277        {
278            sink = new XhtmlBaseSink( writer );
279
280            sink.section2();
281            sink.sectionTitle2();
282            sink.sectionTitle2_();
283            sink.section2_();
284        }
285        finally
286        {
287            sink.close();
288        }
289
290        assertEquals( "<div class=\"section\">" + LS + "<h3></h3></div>", writer.toString() );
291    }
292
293    /**
294     * Test of section3 method, of class XhtmlBaseSink.
295     */
296    public void testSection3()
297    {
298
299        try
300        {
301            sink = new XhtmlBaseSink( writer );
302
303            sink.section3();
304            sink.sectionTitle3();
305            sink.sectionTitle3_();
306            sink.section3_();
307        }
308        finally
309        {
310            sink.close();
311        }
312
313        assertEquals( "<div class=\"section\">" + LS + "<h4></h4></div>", writer.toString() );
314    }
315
316    /**
317     * Test of section4 method, of class XhtmlBaseSink.
318     */
319    public void testSection4()
320    {
321        try
322        {
323            sink = new XhtmlBaseSink( writer );
324
325            sink.section4();
326            sink.sectionTitle4();
327            sink.sectionTitle4_();
328            sink.section4_();
329        }
330        finally
331        {
332            sink.close();
333        }
334
335        assertEquals( "<div class=\"section\">" + LS + "<h5></h5></div>", writer.toString() );
336    }
337
338    /**
339     * Test of section5 method, of class XhtmlBaseSink.
340     */
341    public void testSection5()
342    {
343        try
344        {
345            sink = new XhtmlBaseSink( writer );
346
347            sink.section5();
348            sink.sectionTitle5();
349            sink.sectionTitle5_();
350            sink.section5_();
351        }
352        finally
353        {
354            sink.close();
355        }
356
357        assertEquals( "<div class=\"section\">" + LS + "<h6></h6></div>", writer.toString() );
358    }
359
360    /**
361     * Test of list method, of class XhtmlBaseSink.
362     * @throws java.lang.Exception if any.
363     */
364    public void testList()
365            throws Exception
366    {
367        try
368        {
369            sink = new XhtmlBaseSink( writer );
370
371            sink.list();
372            sink.listItem();
373            sink.listItem_();
374            sink.list_();
375        }
376        finally
377        {
378            sink.close();
379        }
380
381        assertEquals( "<ul>" + LS + "<li></li></ul>", writer.toString() );
382
383        writer =  new StringWriter();
384
385        try
386        {
387            sink = new XhtmlBaseSink( writer );
388
389            sink.list( attributes );
390            sink.listItem( attributes );
391            sink.listItem_();
392            sink.list_();
393        }
394        finally
395        {
396            sink.close();
397        }
398
399        assertEquals( "<ul style=\"bold\">" + LS + "<li style=\"bold\"></li></ul>", writer.toString() );
400    }
401
402    /**
403     * Test of numberedList method, of class XhtmlBaseSink.
404     */
405    public void testNumberedList()
406    {
407        final int numbering = XhtmlBaseSink.NUMBERING_DECIMAL;
408
409        try
410        {
411            sink = new XhtmlBaseSink( writer );
412
413            sink.numberedList( numbering );
414            sink.numberedListItem();
415            sink.numberedListItem_();
416            sink.numberedList_();
417        }
418        finally
419        {
420            sink.close();
421        }
422
423        assertEquals( "<ol style=\"list-style-type: decimal\">" + LS + "<li></li></ol>", writer.toString() );
424
425        writer =  new StringWriter();
426
427        try
428        {
429            sink = new XhtmlBaseSink( writer );
430
431            sink.numberedList( numbering, attributes );
432            sink.numberedListItem( attributes );
433            sink.numberedListItem_();
434            sink.numberedList_();
435        }
436        finally
437        {
438            sink.close();
439        }
440
441        assertEquals( "<ol style=\"list-style-type: decimal\">" + LS + "<li style=\"bold\"></li></ol>", writer.toString() );
442    }
443
444    /**
445     * Test of definitionList method, of class XhtmlBaseSink.
446     */
447    public void testDefinitionList()
448    {
449        try
450        {
451            sink = new XhtmlBaseSink( writer );
452
453            sink.definitionList();
454            sink.definedTerm();
455            sink.definedTerm_();
456            sink.definition();
457            sink.definition_();
458            sink.definitionList_();
459        }
460        finally
461        {
462            sink.close();
463        }
464
465        assertEquals( "<dl>" + LS + "<dt></dt>" + LS + "<dd></dd></dl>", writer.toString() );
466
467        writer =  new StringWriter();
468
469        try
470        {
471            sink = new XhtmlBaseSink( writer );
472
473            sink.definitionList( attributes );
474            sink.definedTerm( attributes );
475            sink.definedTerm_();
476            sink.definition( attributes );
477            sink.definition_();
478            sink.definitionList_();
479        }
480        finally
481        {
482            sink.close();
483        }
484
485        assertEquals( "<dl style=\"bold\">" + LS + "<dt style=\"bold\"></dt>" + LS + "<dd style=\"bold\"></dd></dl>", writer.toString() );
486    }
487
488    /**
489     * Test of figure method, of class XhtmlBaseSink.
490     */
491    public void testFigure()
492    {
493        final String src = "src.jpg";
494
495        try
496        {
497            sink = new XhtmlBaseSink( writer );
498
499            sink.figure( attributes );
500            sink.figureGraphics( src, attributes );
501            sink.figureCaption( attributes );
502            sink.figureCaption_();
503            sink.figure_();
504        }
505        finally
506        {
507            sink.close();
508        }
509
510        assertEquals( "<div style=\"bold\" class=\"figure\">"
511                + "" + LS + "<p align=\"center\"><img src=\"src.jpg\" style=\"bold\" alt=\"\" /></p>"
512                + "" + LS + "<p align=\"center\" style=\"bold\"><i></i></p></div>", writer.toString() );
513    }
514
515    /**
516     * Test of figureGraphics method, of class XhtmlBaseSink.
517     */
518    public void testFigureGraphics()
519    {
520        String src = "source.png";
521
522        try
523        {
524            sink = new XhtmlBaseSink( writer );
525            sink.figureGraphics( src, attributes );
526        }
527        finally
528        {
529            sink.close();
530        }
531
532        assertEquals( "<img src=\"source.png\" style=\"bold\" alt=\"\" />", writer.toString() );
533    }
534
535    /**
536     * Test of paragraph method, of class XhtmlBaseSink.
537     */
538    public void testParagraph()
539    {
540        try
541        {
542            sink = new XhtmlBaseSink( writer );
543
544            sink.paragraph();
545            sink.paragraph_();
546        }
547        finally
548        {
549            sink.close();
550        }
551
552        assertEquals( "<p></p>", writer.toString() );
553
554        writer =  new StringWriter();
555
556        try
557        {
558            sink = new XhtmlBaseSink( writer );
559
560            sink.paragraph( attributes );
561            sink.paragraph_();
562        }
563        finally
564        {
565            sink.close();
566        }
567
568        assertEquals( "<p style=\"bold\"></p>", writer.toString() );
569    }
570
571    /**
572     * Test of verbatim method, of class XhtmlBaseSink.
573     */
574    public void testVerbatim()
575    {
576        try
577        {
578            sink = new XhtmlBaseSink( writer );
579
580            sink.verbatim( true );
581            sink.verbatim_();
582        }
583        finally
584        {
585            sink.close();
586        }
587
588        assertEquals( "<div class=\"source\">" + LS + "<pre></pre></div>", writer.toString() );
589
590        checkVerbatimAttributes( attributes, "<div>" + LS + "<pre style=\"bold\"></pre></div>" );
591
592        final SinkEventAttributes att =
593            new SinkEventAttributeSet( new String[] {SinkEventAttributes.ID, "id"} );
594        checkVerbatimAttributes( att, "<div>" + LS + "<pre id=\"id\"></pre></div>" );
595
596        att.addAttribute( Attribute.CLASS, "class" );
597        checkVerbatimAttributes( att, "<div>" + LS + "<pre id=\"id\" class=\"class\"></pre></div>" );
598
599        att.addAttribute( SinkEventAttributes.DECORATION, "boxed" );
600        checkVerbatimAttributes( att, "<div class=\"source\">" + LS + "<pre id=\"id\" class=\"class\"></pre></div>" );
601
602        att.removeAttribute( Attribute.CLASS.toString() );
603        checkVerbatimAttributes( att, "<div class=\"source\">" + LS + "<pre id=\"id\"></pre></div>" );
604    }
605
606    private void checkVerbatimAttributes( final SinkEventAttributes att, final String expected )
607    {
608
609        writer =  new StringWriter();
610
611        try
612        {
613            sink = new XhtmlBaseSink( writer );
614
615            sink.verbatim( att );
616            sink.verbatim_();
617        }
618        finally
619        {
620            sink.close();
621        }
622
623        assertEquals( expected, writer.toString() );
624    }
625
626    /**
627     * Test of horizontalRule method, of class XhtmlBaseSink.
628     */
629    public void testHorizontalRule()
630    {
631        try
632        {
633            sink = new XhtmlBaseSink( writer );
634
635            sink.horizontalRule();
636            sink.horizontalRule( attributes );
637        }
638        finally
639        {
640            sink.close();
641        }
642
643        assertEquals( "<hr /><hr style=\"bold\" />", writer.toString() );
644    }
645
646    /**
647     * Test of table method, of class XhtmlBaseSink.
648     */
649    public void testTable()
650    {
651        try
652        {
653            sink = new XhtmlBaseSink( writer );
654
655            sink.table( attributes );
656            sink.table_();
657        }
658        finally
659        {
660            sink.close();
661        }
662
663        assertEquals( "</table>", writer.toString() );
664    }
665
666    /**
667     * Test of tableRows method, of class XhtmlBaseSink.
668     */
669    public void testTableRows()
670    {
671        final int[] justification = null;
672        final boolean grid = false;
673
674        try
675        {
676            sink = new XhtmlBaseSink( writer );
677
678            sink.tableRows( justification, grid );
679            sink.tableRows_();
680        }
681        finally
682        {
683            sink.close();
684        }
685
686        assertEquals( "<table border=\"0\" class=\"bodyTable\">", writer.toString() );
687    }
688
689    /**
690     * Test of tableRow method, of class XhtmlBaseSink.
691     */
692    public void testTableRow()
693    {
694        try
695        {
696            sink = new XhtmlBaseSink( writer );
697
698            sink.tableRow( attributes );
699            sink.tableRow_();
700        }
701        finally
702        {
703            sink.close();
704        }
705
706        assertEquals( "<tr class=\"a\" style=\"bold\"></tr>", writer.toString() );
707    }
708
709    /**
710     * Test of tableCell method, of class XhtmlBaseSink.
711     */
712    public void testTableCell()
713    {
714        try
715        {
716            sink = new XhtmlBaseSink( writer );
717
718            sink.tableCell( attributes );
719            sink.tableCell_();
720        }
721        finally
722        {
723            sink.close();
724        }
725
726        assertEquals( "<td style=\"bold\"></td>", writer.toString() );
727    }
728
729    /**
730     * Test of tableHeaderCell method, of class XhtmlBaseSink.
731     */
732    public void testTableHeaderCell()
733    {
734        try
735        {
736            sink = new XhtmlBaseSink( writer );
737
738            sink.tableHeaderCell( attributes );
739            sink.tableHeaderCell_();
740        }
741        finally
742        {
743            sink.close();
744        }
745
746        assertEquals( "<th style=\"bold\"></th>", writer.toString() );
747    }
748
749    /**
750     * Test of tableCaption method, of class XhtmlBaseSink.
751     */
752    public void testTableCaption()
753    {
754        try
755        {
756            sink = new XhtmlBaseSink( writer );
757
758            sink.table();
759            sink.tableRows( null, false );
760            sink.tableCaption( attributes );
761            sink.text( "caption" );
762            sink.tableCaption_();
763            sink.tableRows_();
764            sink.table_();
765        }
766        finally
767        {
768            sink.close();
769        }
770
771        assertEquals( "<table border=\"0\" class=\"bodyTable\">" +
772                "<caption style=\"bold\">caption</caption></table>", writer.toString() );
773    }
774
775    /**
776     * Test of anchor method, of class XhtmlBaseSink.
777     */
778    public void testAnchor()
779    {
780        String name = "anchor";
781
782        try
783        {
784            sink = new XhtmlBaseSink( writer );
785            sink.anchor( name, attributes );
786            sink.anchor_();
787        }
788        finally
789        {
790            sink.close();
791        }
792
793        assertEquals( "<a name=\"anchor\" style=\"bold\"></a>", writer.toString() );
794    }
795
796    /**
797     * Test of link method, of class XhtmlBaseSink.
798     */
799    public void testLink()
800    {
801        final String name = "link.html";
802
803        try
804        {
805            sink = new XhtmlBaseSink( writer );
806            sink.link( name, attributes );
807            sink.link_();
808        }
809        finally
810        {
811            sink.close();
812        }
813
814        assertEquals( "<a href=\"link.html\" style=\"bold\"></a>", writer.toString() );
815    }
816
817    /**
818     * Test of italic/bold/monospaced method, of class XhtmlBaseSink.
819     */
820    public void testItalic()
821    {
822        try
823        {
824            sink = new XhtmlBaseSink( writer );
825            sink.italic();
826            sink.italic_();
827            sink.bold();
828            sink.bold_();
829            sink.monospaced();
830            sink.monospaced_();
831        }
832        finally
833        {
834            sink.close();
835        }
836
837        assertEquals( "<i></i><b></b><tt></tt>", writer.toString() );
838    }
839
840    /**
841     * Test of lineBreak/pageBreak/nonBreakingSpace method, of class XhtmlBaseSink.
842     */
843    public void testLineBreak()
844    {
845        try
846        {
847            sink = new XhtmlBaseSink( writer );
848            sink.lineBreak( attributes );
849            sink.pageBreak();
850            sink.nonBreakingSpace();
851        }
852        finally
853        {
854            sink.close();
855        }
856
857        assertEquals( "<br style=\"bold\" /><!-- PB -->&#160;", writer.toString() );
858    }
859
860    /**
861     * Test of text method, of class XhtmlBaseSink.
862     */
863    public void testText()
864    {
865        String text = "a text & \u00c6";
866
867        try
868        {
869            sink = new XhtmlBaseSink( writer );
870            sink.text( text );
871        }
872        finally
873        {
874            sink.close();
875        }
876
877        assertEquals( "a text &amp; &#xc6;", writer.toString() );
878
879        writer =  new StringWriter();
880
881        try
882        {
883            sink = new XhtmlBaseSink( writer );
884            sink.text( text, attributes );
885        }
886        finally
887        {
888            sink.close();
889        }
890
891        assertEquals( "a text &amp; &#xc6;", writer.toString() );
892    }
893
894    /**
895     * Test of rawText method, of class XhtmlBaseSink.
896     */
897    public void testRawText()
898    {
899        String text = "raw text";
900
901        try
902        {
903            sink = new XhtmlBaseSink( writer );
904            sink.rawText( text );
905        }
906        finally
907        {
908            sink.close();
909        }
910
911        assertEquals( "raw text", writer.toString() );
912    }
913
914    /**
915     * Test of comment method, of class XhtmlBaseSink.
916     */
917    public void testComment()
918    {
919        try
920        {
921            sink = new XhtmlBaseSink( writer );
922            sink.comment( "a comment" );
923            sink.comment( " a comment" );
924            sink.comment( "a comment " );
925            sink.comment( " a comment " );
926        }
927        finally
928        {
929            sink.close();
930        }
931
932        assertEquals( "<!--a comment--><!-- a comment--><!--a comment --><!-- a comment -->", writer.toString() );
933    }
934
935    /**
936     * Test of unknown method, of class XhtmlBaseSink.
937     */
938    public void testUnknown()
939    {
940        final String name = "unknown";
941        final Object[] requiredParams = null;
942
943        try
944        {
945            sink = new XhtmlBaseSink( writer );
946            sink.unknown( name, requiredParams, attributes );
947        }
948        finally
949        {
950            sink.close();
951        }
952
953        assertEquals( "", writer.toString() );
954    }
955
956    /**
957     * Test entities in attribute values.
958     */
959    public void testAttributeEntities()
960    {
961        final Object[] startTag = new Object[] { new Integer( XhtmlBaseSink.TAG_TYPE_START ) };
962        final Object[] endTag = new Object[] { new Integer( XhtmlBaseSink.TAG_TYPE_END ) };
963        final String script = XhtmlBaseSink.SCRIPT.toString();
964        final SinkEventAttributes src = new SinkEventAttributeSet(
965                new String[] {SinkEventAttributes.SRC.toString(), "http://ex.com/ex.js?v=l&l=e"} );
966
967        try
968        {
969            sink = new XhtmlBaseSink( writer );
970
971            sink.unknown( script, startTag, src );
972            sink.unknown( script, endTag, null );
973
974            sink.figureGraphics( "http://ex.com/ex.jpg?v=l&l=e", src );
975        }
976        finally
977        {
978            sink.close();
979        }
980
981        String result = writer.toString();
982
983        assertTrue( result.contains( "ex.js?v=l&amp;l=e" ) );
984        assertTrue( result.contains( "ex.jpg?v=l&amp;l=e" ) );
985    }
986
987    /**
988     * Test of entity.
989     */
990    public void testEntity()
991    {
992        // DOXIA-314
993        String text = "a text '&#x1d7ed;'";
994
995        try
996        {
997            sink = new XhtmlBaseSink( writer );
998            sink.text( text );
999        }
1000        finally
1001        {
1002            sink.close();
1003        }
1004
1005        assertEquals( "a text '&#x1d7ed;'", writer.toString() );
1006    }
1007
1008    /**
1009     * Test unicode chracters in tables. DOXIA-433.
1010     */
1011    public void testSpecialCharacters()
1012    {
1013        try
1014        {
1015            sink = new XhtmlBaseSink( writer );
1016            sink.table( null );
1017            sink.tableRows( null, true );
1018            sink.tableRow( null );
1019            sink.tableCell();
1020            sink.text( "\u2713", null );
1021            sink.tableCell_();
1022            sink.tableRow_();
1023            sink.tableRows_();
1024            sink.table_();
1025        }
1026        finally
1027        {
1028            sink.close();
1029        }
1030
1031        final String result = writer.toString();
1032
1033        assertTrue( result.contains( "&#x2713;" ) );
1034    }
1035}