001    /*
002     * Copyright 2007 - 2010 JEuclid, http://jeuclid.sf.net
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    /* $Id: DOMModelTest.java,v 92b6a7c39d7f 2010/08/11 20:23:17 max $ */
018    
019    package net.sourceforge.jeuclid.test;
020    
021    import java.lang.reflect.Method;
022    import java.lang.reflect.Modifier;
023    import java.util.Set;
024    import java.util.TreeSet;
025    
026    import net.sourceforge.jeuclid.DOMBuilder;
027    import net.sourceforge.jeuclid.MathMLParserSupport;
028    import net.sourceforge.jeuclid.MathMLSerializer;
029    import net.sourceforge.jeuclid.elements.JEuclidElementFactory;
030    import net.sourceforge.jeuclid.elements.content.semantic.Annotation;
031    import net.sourceforge.jeuclid.elements.content.semantic.Semantics;
032    import net.sourceforge.jeuclid.elements.generic.DocumentElement;
033    import net.sourceforge.jeuclid.elements.generic.MathImpl;
034    import net.sourceforge.jeuclid.elements.presentation.enlivening.Maction;
035    import net.sourceforge.jeuclid.elements.presentation.general.Menclose;
036    import net.sourceforge.jeuclid.elements.presentation.general.Merror;
037    import net.sourceforge.jeuclid.elements.presentation.general.Mfenced;
038    import net.sourceforge.jeuclid.elements.presentation.general.Mfrac;
039    import net.sourceforge.jeuclid.elements.presentation.general.Mpadded;
040    import net.sourceforge.jeuclid.elements.presentation.general.Mphantom;
041    import net.sourceforge.jeuclid.elements.presentation.general.Mroot;
042    import net.sourceforge.jeuclid.elements.presentation.general.Mrow;
043    import net.sourceforge.jeuclid.elements.presentation.general.Msqrt;
044    import net.sourceforge.jeuclid.elements.presentation.general.Mstyle;
045    import net.sourceforge.jeuclid.elements.presentation.script.Mmultiscripts;
046    import net.sourceforge.jeuclid.elements.presentation.script.Mover;
047    import net.sourceforge.jeuclid.elements.presentation.script.Mprescripts;
048    import net.sourceforge.jeuclid.elements.presentation.script.Msub;
049    import net.sourceforge.jeuclid.elements.presentation.script.Msubsup;
050    import net.sourceforge.jeuclid.elements.presentation.script.Msup;
051    import net.sourceforge.jeuclid.elements.presentation.script.Munder;
052    import net.sourceforge.jeuclid.elements.presentation.script.Munderover;
053    import net.sourceforge.jeuclid.elements.presentation.script.None;
054    import net.sourceforge.jeuclid.elements.presentation.table.Maligngroup;
055    import net.sourceforge.jeuclid.elements.presentation.table.Malignmark;
056    import net.sourceforge.jeuclid.elements.presentation.table.Mlabeledtr;
057    import net.sourceforge.jeuclid.elements.presentation.table.Mtable;
058    import net.sourceforge.jeuclid.elements.presentation.table.Mtd;
059    import net.sourceforge.jeuclid.elements.presentation.table.Mtr;
060    import net.sourceforge.jeuclid.elements.presentation.token.Mglyph;
061    import net.sourceforge.jeuclid.elements.presentation.token.Mi;
062    import net.sourceforge.jeuclid.elements.presentation.token.Mn;
063    import net.sourceforge.jeuclid.elements.presentation.token.Mo;
064    import net.sourceforge.jeuclid.elements.presentation.token.Ms;
065    import net.sourceforge.jeuclid.elements.presentation.token.Mspace;
066    import net.sourceforge.jeuclid.elements.presentation.token.Mtext;
067    
068    import org.junit.Assert;
069    import org.junit.Test;
070    import org.w3c.dom.Document;
071    import org.w3c.dom.events.Event;
072    import org.w3c.dom.events.EventListener;
073    import org.w3c.dom.events.EventTarget;
074    import org.w3c.dom.mathml.MathMLActionElement;
075    import org.w3c.dom.mathml.MathMLAlignGroupElement;
076    import org.w3c.dom.mathml.MathMLAlignMarkElement;
077    import org.w3c.dom.mathml.MathMLAnnotationElement;
078    import org.w3c.dom.mathml.MathMLDocument;
079    import org.w3c.dom.mathml.MathMLElement;
080    import org.w3c.dom.mathml.MathMLEncloseElement;
081    import org.w3c.dom.mathml.MathMLFencedElement;
082    import org.w3c.dom.mathml.MathMLFractionElement;
083    import org.w3c.dom.mathml.MathMLGlyphElement;
084    import org.w3c.dom.mathml.MathMLLabeledRowElement;
085    import org.w3c.dom.mathml.MathMLMathElement;
086    import org.w3c.dom.mathml.MathMLMultiScriptsElement;
087    import org.w3c.dom.mathml.MathMLOperatorElement;
088    import org.w3c.dom.mathml.MathMLPaddedElement;
089    import org.w3c.dom.mathml.MathMLPresentationContainer;
090    import org.w3c.dom.mathml.MathMLPresentationToken;
091    import org.w3c.dom.mathml.MathMLRadicalElement;
092    import org.w3c.dom.mathml.MathMLScriptElement;
093    import org.w3c.dom.mathml.MathMLSemanticsElement;
094    import org.w3c.dom.mathml.MathMLSpaceElement;
095    import org.w3c.dom.mathml.MathMLStringLitElement;
096    import org.w3c.dom.mathml.MathMLStyleElement;
097    import org.w3c.dom.mathml.MathMLTableCellElement;
098    import org.w3c.dom.mathml.MathMLTableElement;
099    import org.w3c.dom.mathml.MathMLTableRowElement;
100    import org.w3c.dom.mathml.MathMLUnderOverElement;
101    
102    /**
103     * Various tests for the DOM model.
104     *
105     * @version $Revision: 92b6a7c39d7f $
106     */
107    // CHECKSTYLE:OFF
108    public class DOMModelTest {
109        // CHECKSTYLE:ON
110    
111        private int docCount;
112    
113        private int mathCount;
114    
115        private int miCount;
116    
117        /**
118         * Default constructor.
119         */
120        public DOMModelTest() {
121            // Empty on purpose.
122        }
123    
124        /**
125         * Tests is the "id" attribute works.
126         *
127         * @throws Exception
128         *             if anything goes wrong.
129         */
130        @Test
131        public void testID() throws Exception {
132            final Document docWithID = MathMLParserSupport
133                    .parseString("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><math mode=\"display\">"
134                            + "<mrow id='abc'><mn>1</mn></mrow></math>");
135    
136            final MathMLDocument docElement = DOMBuilder.getInstance()
137                    .createJeuclidDom(docWithID);
138    
139            final MathMLMathElement mathElement = (MathMLMathElement) docElement
140                    .getFirstChild();
141    
142            Assert.assertEquals(mathElement.getDisplay(), "block");
143            final MathMLPresentationContainer row = (MathMLPresentationContainer) mathElement
144                    .getFirstChild();
145            Assert.assertNotNull(row);
146            Assert.assertEquals(row.getId(), "abc");
147        }
148    
149        /**
150         * Tests if serialization works.
151         *
152         * @throws Exception
153         *             if anything goes wrong.
154         */
155        @Test
156        public void testSerialization() throws Exception {
157            final String shouldBe = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><math mode=\"display\" xmlns='http://www.w3.org/1998/Math/MathML'>"
158                    + "<mrow id='abc'><mn>1</mn></mrow></math>";
159            final Document origDoc = MathMLParserSupport.parseString(shouldBe);
160            final MathMLDocument mathMLDoc = DOMBuilder.getInstance()
161                    .createJeuclidDom(origDoc);
162            final String reserialStr = MathMLSerializer.serializeDocument(
163                    mathMLDoc, false, false);
164    
165            final Document reserial = MathMLParserSupport.parseString(reserialStr);
166            Assert.assertTrue("is: " + reserialStr + "\nshould be: " + shouldBe,
167                    reserial.isEqualNode(origDoc));
168        }
169    
170        /**
171         * Tests if serialization with malignmark works.
172         *
173         * @throws Exception
174         *             if anything goes wrong.
175         */
176        @Test
177        public void testSerialization2() throws Exception {
178            final String shouldBe = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><math mode=\"display\" xmlns='http://www.w3.org/1998/Math/MathML'>"
179                    + "<mtext>Alignment<malignmark/>Test</mtext></math>";
180            final Document origDoc = MathMLParserSupport.parseString(shouldBe);
181            final MathMLDocument mathMLDoc = DOMBuilder.getInstance()
182                    .createJeuclidDom(origDoc);
183            final String reserialStr = MathMLSerializer.serializeDocument(
184                    mathMLDoc, false, false);
185    
186            final Document reserial = MathMLParserSupport.parseString(reserialStr);
187            Assert.assertTrue("is: " + reserialStr + "\nshould be: " + shouldBe,
188                    reserial.isEqualNode(origDoc));
189        }
190    
191        /**
192         * Tests is all attributes on mathOperator work.
193         *
194         * @throws Exception
195         *             if anything goes wrong.
196         */
197        @Test
198        public void testMOAttrs() throws Exception {
199            final Document doc = MathMLParserSupport
200                    .parseString("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><math mode=\"display\">"
201                            + "<mo stretchy='true'>X</mo>"
202                            + "<mo stretchy='false'>Y</mo>"
203                            + "<mo>&#x0007d;</mo>"
204                            + "<mo>&#x02254;</mo>"
205                            + "<mo>&#x0201d;</mo>"
206                            + "<mo stretchy='false'>)</mo>"
207                            + "<mo>)</mo>"
208                            + "</math>");
209            final MathMLDocument docElement = DOMBuilder.getInstance()
210                    .createJeuclidDom(doc);
211    
212            final MathMLMathElement mathElement = (MathMLMathElement) docElement
213                    .getFirstChild();
214    
215            final MathMLOperatorElement mo = (MathMLOperatorElement) mathElement
216                    .getChildNodes().item(0);
217            Assert.assertNotNull(mo);
218            Assert.assertTrue(Boolean.parseBoolean(mo.getStretchy()));
219            final Mo mo2 = (Mo) mathElement.getChildNodes().item(1);
220            Assert.assertNotNull(mo2);
221            Assert.assertFalse(Boolean.parseBoolean(mo2.getStretchy()));
222            final Mo mo3 = (Mo) mathElement.getChildNodes().item(2);
223            // Should be strechty, since it is fence
224            Assert.assertTrue(Boolean.parseBoolean(mo3.getStretchy()));
225            final Mo mo4 = (Mo) mathElement.getChildNodes().item(3);
226            Assert.assertFalse(Boolean.parseBoolean(mo4.getStretchy()));
227            final Mo mo5 = (Mo) mathElement.getChildNodes().item(4);
228            Assert.assertTrue(Boolean.parseBoolean(mo5.getStretchy()));
229            final Mo mo6 = (Mo) mathElement.getChildNodes().item(5);
230            Assert.assertFalse(Boolean.parseBoolean(mo6.getStretchy()));
231            final Mo mo7 = (Mo) mathElement.getChildNodes().item(6);
232            Assert.assertTrue(Boolean.parseBoolean(mo7.getStretchy()));
233        }
234    
235        /**
236         * Tests of objects created from MathElementFactory implement the proper
237         * interfaces from W3C Dom.
238         *
239         * @throws Exception
240         *             if anything goes wrong.
241         */
242        @Test
243        public void testInterfaces() throws Exception {
244    
245            // This mapping is taken straight from Table D.2.2, MathML 2.0 spec
246            // TODO: Someday none of these should be commented out.
247    
248            // TODO: Use DOM instead;
249            final Document ownerDocument = new DocumentElement();
250    
251            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "math",
252                    ownerDocument) instanceof MathMLMathElement);
253            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mi",
254                    ownerDocument) instanceof MathMLPresentationToken);
255            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mn",
256                    ownerDocument) instanceof MathMLPresentationToken);
257            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mo",
258                    ownerDocument) instanceof MathMLOperatorElement);
259            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mtext",
260                    ownerDocument) instanceof MathMLPresentationToken);
261            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mspace",
262                    ownerDocument) instanceof MathMLSpaceElement);
263            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "ms",
264                    ownerDocument) instanceof MathMLStringLitElement);
265            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mglyph",
266                    ownerDocument) instanceof MathMLGlyphElement);
267            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mrow",
268                    ownerDocument) instanceof MathMLPresentationContainer);
269            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mfrac",
270                    ownerDocument) instanceof MathMLFractionElement);
271            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "msqrt",
272                    ownerDocument) instanceof MathMLRadicalElement);
273            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mroot",
274                    ownerDocument) instanceof MathMLRadicalElement);
275            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mstyle",
276                    ownerDocument) instanceof MathMLStyleElement);
277            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "merror",
278                    ownerDocument) instanceof MathMLPresentationContainer);
279            Assert.assertTrue(JEuclidElementFactory.elementFromName(null,
280                    "mpadded", ownerDocument) instanceof MathMLPaddedElement);
281            Assert
282                    .assertTrue(JEuclidElementFactory.elementFromName(null,
283                            "mphantom", ownerDocument) instanceof MathMLPresentationContainer);
284            Assert.assertTrue(JEuclidElementFactory.elementFromName(null,
285                    "mfenced", ownerDocument) instanceof MathMLFencedElement);
286            Assert.assertTrue(JEuclidElementFactory.elementFromName(null,
287                    "menclose", ownerDocument) instanceof MathMLEncloseElement);
288            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "msub",
289                    ownerDocument) instanceof MathMLScriptElement);
290            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "msup",
291                    ownerDocument) instanceof MathMLScriptElement);
292            Assert.assertTrue(JEuclidElementFactory.elementFromName(null,
293                    "msubsup", ownerDocument) instanceof MathMLScriptElement);
294            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "munder",
295                    ownerDocument) instanceof MathMLUnderOverElement);
296            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mover",
297                    ownerDocument) instanceof MathMLUnderOverElement);
298            Assert.assertTrue(JEuclidElementFactory.elementFromName(null,
299                    "munderover", ownerDocument) instanceof MathMLUnderOverElement);
300            Assert
301                    .assertTrue(JEuclidElementFactory.elementFromName(null,
302                            "mmultiscripts", ownerDocument) instanceof MathMLMultiScriptsElement);
303            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mtable",
304                    ownerDocument) instanceof MathMLTableElement);
305            Assert
306                    .assertTrue(JEuclidElementFactory.elementFromName(null,
307                            "mlabeledtr", ownerDocument) instanceof MathMLLabeledRowElement);
308            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mtr",
309                    ownerDocument) instanceof MathMLTableRowElement);
310            Assert.assertTrue(JEuclidElementFactory.elementFromName(null, "mtd",
311                    ownerDocument) instanceof MathMLTableCellElement);
312            Assert
313                    .assertTrue(JEuclidElementFactory.elementFromName(null,
314                            "maligngroup", ownerDocument) instanceof MathMLAlignGroupElement);
315            Assert.assertTrue(JEuclidElementFactory.elementFromName(null,
316                    "malignmark", ownerDocument) instanceof MathMLAlignMarkElement);
317            Assert.assertTrue(JEuclidElementFactory.elementFromName(null,
318                    "maction", ownerDocument) instanceof MathMLActionElement);
319            // Assert
320            // .assertTrue(MathElementFactory.elementFromName("cn", aMap,
321            // base) instanceof MathMLCnElement);
322            // Assert
323            // .assertTrue(MathElementFactory.elementFromName("ci", aMap,
324            // base) instanceof MathMLCiElement);
325            // Assert.assertTrue(MathElementFactory.elementFromName("csymbol",
326            // aMap,
327            // base) instanceof MathMLCsymbolElement);
328            // Assert.assertTrue(MathElementFactory.elementFromName("apply", aMap,
329            // base) instanceof MathMLApplyElement);
330            // Assert.assertTrue(MathElementFactory.elementFromName("reln", aMap,
331            // base) instanceof MathMLContentContainer);
332            // Assert
333            // .assertTrue(MathElementFactory.elementFromName("fn", aMap,
334            // base) instanceof MathMLFnElement);
335            // Assert.assertTrue(MathElementFactory.elementFromName("interval",
336            // aMap) instanceof MathMLIntervalElement);
337            // Assert.assertTrue(MathElementFactory.elementFromName("inverse",
338            // aMap,
339            // base) instanceof MathMLPredefinedSymbol);
340            // Assert.assertTrue(MathElementFactory.elementFromName("condition",
341            // aMap) instanceof MathMLConditionElement);
342            // Assert.assertTrue(MathElementFactory.elementFromName("declare",
343            // aMap,
344            // base) instanceof MathMLDeclareElement);
345            // Assert.assertTrue(MathElementFactory.elementFromName("lambda",
346            // aMap,
347            // base) instanceof MathMLLambdaElement);
348            // Assert.assertTrue(MathElementFactory.elementFromName("compose",
349            // aMap,
350            // base) instanceof MathMLPredefinedSymbol);
351            // Assert.assertTrue(MathElementFactory.elementFromName("ident", aMap,
352            // base) instanceof MathMLPredefinedSymbol);
353            // Assert.assertTrue(MathElementFactory.elementFromName("domain",
354            // aMap,
355            // base) instanceof MathMLPredefinedSymbol);
356            // Assert.assertTrue(MathElementFactory.elementFromName("codomain",
357            // aMap) instanceof MathMLPredefinedSymbol);
358            // Assert.assertTrue(MathElementFactory.elementFromName("image", aMap,
359            // base) instanceof MathMLPredefinedSymbol);
360            // Assert
361            // .assertTrue(MathElementFactory.elementFromName(
362            // "domainofapplication", aMap) instanceof
363            // MathMLContentContainer);
364            // Assert.assertTrue(MathElementFactory.elementFromName("piecewise",
365            // aMap) instanceof MathMLPiecewiseElement);
366            // Assert.assertTrue(MathElementFactory.elementFromName("piece", aMap,
367            // base) instanceof MathMLCaseElement);
368            // Assert.assertTrue(MathElementFactory.elementFromName("otherwise",
369            // aMap) instanceof MathMLContentContainer);
370            // Assert.assertTrue(MathElementFactory.elementFromName("quotient",
371            // aMap) instanceof MathMLPredefinedSymbol);
372            // Assert.assertTrue(MathElementFactory.elementFromName("exp", aMap,
373            // base) instanceof MathMLPredefinedSymbol);
374            // Assert.assertTrue(MathElementFactory.elementFromName("factorial",
375            // aMap) instanceof MathMLPredefinedSymbol);
376            // Assert.assertTrue(MathElementFactory.elementFromName("divide",
377            // aMap,
378            // base) instanceof MathMLPredefinedSymbol);
379            // Assert.assertTrue(MathElementFactory.elementFromName("max", aMap,
380            // base) instanceof MathMLPredefinedSymbol);
381            // Assert.assertTrue(MathElementFactory.elementFromName("min", aMap,
382            // base) instanceof MathMLPredefinedSymbol);
383            // Assert.assertTrue(MathElementFactory.elementFromName("minus", aMap,
384            // base) instanceof MathMLPredefinedSymbol);
385            // Assert.assertTrue(MathElementFactory.elementFromName("plus", aMap,
386            // base) instanceof MathMLPredefinedSymbol);
387            // Assert.assertTrue(MathElementFactory.elementFromName("power", aMap,
388            // base) instanceof MathMLPredefinedSymbol);
389            // Assert.assertTrue(MathElementFactory.elementFromName("rem", aMap,
390            // base) instanceof MathMLPredefinedSymbol);
391            // Assert.assertTrue(MathElementFactory.elementFromName("times", aMap,
392            // base) instanceof MathMLPredefinedSymbol);
393            // Assert.assertTrue(MathElementFactory.elementFromName("root", aMap,
394            // base) instanceof MathMLPredefinedSymbol);
395            // Assert.assertTrue(MathElementFactory.elementFromName("gcd", aMap,
396            // base) instanceof MathMLPredefinedSymbol);
397            // Assert.assertTrue(MathElementFactory.elementFromName("and", aMap,
398            // base) instanceof MathMLPredefinedSymbol);
399            // Assert
400            // .assertTrue(MathElementFactory.elementFromName("or", aMap,
401            // base) instanceof MathMLPredefinedSymbol);
402            // Assert.assertTrue(MathElementFactory.elementFromName("xor", aMap,
403            // base) instanceof MathMLPredefinedSymbol);
404            // Assert.assertTrue(MathElementFactory.elementFromName("not", aMap,
405            // base) instanceof MathMLPredefinedSymbol);
406            // Assert.assertTrue(MathElementFactory.elementFromName("implies",
407            // aMap,
408            // base) instanceof MathMLPredefinedSymbol);
409            // Assert.assertTrue(MathElementFactory.elementFromName("forall",
410            // aMap,
411            // base) instanceof MathMLPredefinedSymbol);
412            // Assert.assertTrue(MathElementFactory.elementFromName("exists",
413            // aMap,
414            // base) instanceof MathMLPredefinedSymbol);
415            // Assert.assertTrue(MathElementFactory.elementFromName("abs", aMap,
416            // base) instanceof MathMLPredefinedSymbol);
417            // Assert.assertTrue(MathElementFactory.elementFromName("conjugate",
418            // aMap) instanceof MathMLPredefinedSymbol);
419            // Assert.assertTrue(MathElementFactory.elementFromName("arg", aMap,
420            // base) instanceof MathMLPredefinedSymbol);
421            // Assert.assertTrue(MathElementFactory.elementFromName("real", aMap,
422            // base) instanceof MathMLPredefinedSymbol);
423            // Assert.assertTrue(MathElementFactory.elementFromName("imaginary",
424            // aMap) instanceof MathMLPredefinedSymbol);
425            // Assert.assertTrue(MathElementFactory.elementFromName("lcm", aMap,
426            // base) instanceof MathMLPredefinedSymbol);
427            // Assert.assertTrue(MathElementFactory.elementFromName("floor", aMap,
428            // base) instanceof MathMLPredefinedSymbol);
429            // Assert.assertTrue(MathElementFactory.elementFromName("ceiling",
430            // aMap,
431            // base) instanceof MathMLPredefinedSymbol);
432            // Assert
433            // .assertTrue(MathElementFactory.elementFromName("eq", aMap,
434            // base) instanceof MathMLPredefinedSymbol);
435            // Assert.assertTrue(MathElementFactory.elementFromName("neq", aMap,
436            // base) instanceof MathMLPredefinedSymbol);
437            // Assert
438            // .assertTrue(MathElementFactory.elementFromName("gt", aMap,
439            // base) instanceof MathMLPredefinedSymbol);
440            // Assert
441            // .assertTrue(MathElementFactory.elementFromName("lt", aMap,
442            // base) instanceof MathMLPredefinedSymbol);
443            // Assert.assertTrue(MathElementFactory.elementFromName("geq", aMap,
444            // base) instanceof MathMLPredefinedSymbol);
445            // Assert.assertTrue(MathElementFactory.elementFromName("leq", aMap,
446            // base) instanceof MathMLPredefinedSymbol);
447            // Assert.assertTrue(MathElementFactory.elementFromName("equivalent",
448            // aMap) instanceof MathMLPredefinedSymbol);
449            // Assert.assertTrue(MathElementFactory.elementFromName("approx",
450            // aMap,
451            // base) instanceof MathMLPredefinedSymbol);
452            // Assert.assertTrue(MathElementFactory.elementFromName("factorof",
453            // aMap) instanceof MathMLPredefinedSymbol);
454            // Assert.assertTrue(MathElementFactory.elementFromName("int", aMap,
455            // base) instanceof MathMLPredefinedSymbol);
456            // Assert.assertTrue(MathElementFactory.elementFromName("diff", aMap,
457            // base) instanceof MathMLPredefinedSymbol);
458            // Assert.assertTrue(MathElementFactory.elementFromName("partialdiff",
459            // aMap) instanceof MathMLPredefinedSymbol);
460            // Assert.assertTrue(MathElementFactory.elementFromName("lowlimit",
461            // aMap) instanceof MathMLContentContainer);
462            // Assert.assertTrue(MathElementFactory.elementFromName("uplimit",
463            // aMap,
464            // base) instanceof MathMLContentContainer);
465            // Assert.assertTrue(MathElementFactory.elementFromName("bvar", aMap,
466            // base) instanceof MathMLBvarElement);
467            // Assert.assertTrue(MathElementFactory.elementFromName("degree",
468            // aMap,
469            // base) instanceof MathMLContentContainer);
470            // Assert.assertTrue(MathElementFactory.elementFromName("divergence",
471            // aMap) instanceof MathMLPredefinedSymbol);
472            // Assert.assertTrue(MathElementFactory.elementFromName("grad", aMap,
473            // base) instanceof MathMLPredefinedSymbol);
474            // Assert.assertTrue(MathElementFactory.elementFromName("curl", aMap,
475            // base) instanceof MathMLPredefinedSymbol);
476            // Assert.assertTrue(MathElementFactory.elementFromName("laplacian",
477            // aMap) instanceof MathMLPredefinedSymbol);
478            // Assert.assertTrue(MathElementFactory.elementFromName("set", aMap,
479            // base) instanceof MathMLSetElement);
480            // Assert.assertTrue(MathElementFactory.elementFromName("list", aMap,
481            // base) instanceof MathMLListElement);
482            // Assert.assertTrue(MathElementFactory.elementFromName("union", aMap,
483            // base) instanceof MathMLPredefinedSymbol);
484            // Assert.assertTrue(MathElementFactory.elementFromName("intersect",
485            // aMap) instanceof MathMLPredefinedSymbol);
486            // Assert
487            // .assertTrue(MathElementFactory.elementFromName("in", aMap,
488            // base) instanceof MathMLPredefinedSymbol);
489            // Assert.assertTrue(MathElementFactory.elementFromName("notin", aMap,
490            // base) instanceof MathMLPredefinedSymbol);
491            // Assert.assertTrue(MathElementFactory.elementFromName("subset",
492            // aMap,
493            // base) instanceof MathMLPredefinedSymbol);
494            // Assert.assertTrue(MathElementFactory.elementFromName("prsubset",
495            // aMap) instanceof MathMLPredefinedSymbol);
496            // Assert.assertTrue(MathElementFactory.elementFromName("notsubset",
497            // aMap) instanceof MathMLPredefinedSymbol);
498            // Assert.assertTrue(MathElementFactory.elementFromName("notprsubset",
499            // aMap) instanceof MathMLPredefinedSymbol);
500            // Assert.assertTrue(MathElementFactory.elementFromName("setdiff",
501            // aMap,
502            // base) instanceof MathMLPredefinedSymbol);
503            // Assert.assertTrue(MathElementFactory.elementFromName("card", aMap,
504            // base) instanceof MathMLPredefinedSymbol);
505            // Assert
506            // .assertTrue(MathElementFactory.elementFromName(
507            // "cartesianproduct", aMap) instanceof MathMLPredefinedSymbol);
508            // Assert.assertTrue(MathElementFactory.elementFromName("sum", aMap,
509            // base) instanceof MathMLPredefinedSymbol);
510            // Assert.assertTrue(MathElementFactory.elementFromName("product",
511            // aMap,
512            // base) instanceof MathMLPredefinedSymbol);
513            // Assert.assertTrue(MathElementFactory.elementFromName("limit", aMap,
514            // base) instanceof MathMLPredefinedSymbol);
515    
516            // This interface does not exist.
517            // Assert.assertTrue(MathElementFactory.elementFromName("tendsto",
518            // aMap,
519            // base) instanceof MathMLTendsToElement);
520    
521            // Assert.assertTrue(MathElementFactory.elementFromName("exp", aMap,
522            // base) instanceof MathMLPredefinedSymbol);
523            // Assert
524            // .assertTrue(MathElementFactory.elementFromName("ln", aMap,
525            // base) instanceof MathMLPredefinedSymbol);
526            // Assert.assertTrue(MathElementFactory.elementFromName("log", aMap,
527            // base) instanceof MathMLPredefinedSymbol);
528            // Assert.assertTrue(MathElementFactory.elementFromName("sin", aMap,
529            // base) instanceof MathMLPredefinedSymbol);
530            // Assert.assertTrue(MathElementFactory.elementFromName("cos", aMap,
531            // base) instanceof MathMLPredefinedSymbol);
532            // Assert.assertTrue(MathElementFactory.elementFromName("tan", aMap,
533            // base) instanceof MathMLPredefinedSymbol);
534            // Assert.assertTrue(MathElementFactory.elementFromName("sec", aMap,
535            // base) instanceof MathMLPredefinedSymbol);
536            // Assert.assertTrue(MathElementFactory.elementFromName("csc", aMap,
537            // base) instanceof MathMLPredefinedSymbol);
538            // Assert.assertTrue(MathElementFactory.elementFromName("cot", aMap,
539            // base) instanceof MathMLPredefinedSymbol);
540            // Assert.assertTrue(MathElementFactory.elementFromName("sinh", aMap,
541            // base) instanceof MathMLPredefinedSymbol);
542            // Assert.assertTrue(MathElementFactory.elementFromName("cosh", aMap,
543            // base) instanceof MathMLPredefinedSymbol);
544            // Assert.assertTrue(MathElementFactory.elementFromName("tanh", aMap,
545            // base) instanceof MathMLPredefinedSymbol);
546            // Assert.assertTrue(MathElementFactory.elementFromName("sech", aMap,
547            // base) instanceof MathMLPredefinedSymbol);
548            // Assert.assertTrue(MathElementFactory.elementFromName("csch", aMap,
549            // base) instanceof MathMLPredefinedSymbol);
550            // Assert.assertTrue(MathElementFactory.elementFromName("coth", aMap,
551            // base) instanceof MathMLPredefinedSymbol);
552            // Assert.assertTrue(MathElementFactory.elementFromName("arcsin",
553            // aMap,
554            // base) instanceof MathMLPredefinedSymbol);
555            // Assert.assertTrue(MathElementFactory.elementFromName("arccos",
556            // aMap,
557            // base) instanceof MathMLPredefinedSymbol);
558            // Assert.assertTrue(MathElementFactory.elementFromName("arctan",
559            // aMap,
560            // base) instanceof MathMLPredefinedSymbol);
561            // Assert.assertTrue(MathElementFactory.elementFromName("arccosh",
562            // aMap,
563            // base) instanceof MathMLPredefinedSymbol);
564            // Assert.assertTrue(MathElementFactory.elementFromName("arccot",
565            // aMap,
566            // base) instanceof MathMLPredefinedSymbol);
567            // Assert.assertTrue(MathElementFactory.elementFromName("arccoth",
568            // aMap,
569            // base) instanceof MathMLPredefinedSymbol);
570            // Assert.assertTrue(MathElementFactory.elementFromName("arccsc",
571            // aMap,
572            // base) instanceof MathMLPredefinedSymbol);
573            // Assert.assertTrue(MathElementFactory.elementFromName("arccsch",
574            // aMap,
575            // base) instanceof MathMLPredefinedSymbol);
576            // Assert.assertTrue(MathElementFactory.elementFromName("arcsec",
577            // aMap,
578            // base) instanceof MathMLPredefinedSymbol);
579            // Assert.assertTrue(MathElementFactory.elementFromName("arcsech",
580            // aMap,
581            // base) instanceof MathMLPredefinedSymbol);
582            // Assert.assertTrue(MathElementFactory.elementFromName("arcsinh",
583            // aMap,
584            // base) instanceof MathMLPredefinedSymbol);
585            // Assert.assertTrue(MathElementFactory.elementFromName("arctanh",
586            // aMap,
587            // base) instanceof MathMLPredefinedSymbol);
588            // Assert.assertTrue(MathElementFactory.elementFromName("mean", aMap,
589            // base) instanceof MathMLPredefinedSymbol);
590            // Assert.assertTrue(MathElementFactory.elementFromName("sdev", aMap,
591            // base) instanceof MathMLPredefinedSymbol);
592            // Assert.assertTrue(MathElementFactory.elementFromName("variance",
593            // aMap) instanceof MathMLPredefinedSymbol);
594            // Assert.assertTrue(MathElementFactory.elementFromName("median",
595            // aMap,
596            // base) instanceof MathMLPredefinedSymbol);
597            // Assert.assertTrue(MathElementFactory.elementFromName("mode", aMap,
598            // base) instanceof MathMLPredefinedSymbol);
599            // Assert.assertTrue(MathElementFactory.elementFromName("moment",
600            // aMap,
601            // base) instanceof MathMLPredefinedSymbol);
602            // Assert.assertTrue(MathElementFactory.elementFromName("momentabout",
603            // aMap) instanceof MathMLContentContainer);
604            // Assert.assertTrue(MathElementFactory.elementFromName("vector",
605            // aMap,
606            // base) instanceof MathMLVectorElement);
607            // Assert.assertTrue(MathElementFactory.elementFromName("matrix",
608            // aMap,
609            // base) instanceof MathMLMatrixElement);
610            // Assert.assertTrue(MathElementFactory.elementFromName("matrixrow",
611            // aMap) instanceof MathMLMatrixrowElement);
612            // Assert.assertTrue(MathElementFactory.elementFromName("determinant",
613            // aMap) instanceof MathMLPredefinedSymbol);
614            // Assert.assertTrue(MathElementFactory.elementFromName("transpose",
615            // aMap) instanceof MathMLPredefinedSymbol);
616            // Assert.assertTrue(MathElementFactory.elementFromName("selector",
617            // aMap) instanceof MathMLPredefinedSymbol);
618            // Assert.assertTrue(MathElementFactory.elementFromName("vectorproduct",
619            // aMap) instanceof MathMLPredefinedSymbol);
620            // Assert.assertTrue(MathElementFactory.elementFromName("scalarproduct",
621            // aMap) instanceof MathMLPredefinedSymbol);
622            // Assert.assertTrue(MathElementFactory.elementFromName("outerproduct",
623            // aMap) instanceof MathMLPredefinedSymbol);
624            Assert
625                    .assertTrue(JEuclidElementFactory.elementFromName(null,
626                            "annotation", ownerDocument) instanceof MathMLAnnotationElement);
627            Assert.assertTrue(JEuclidElementFactory.elementFromName(null,
628                    "semantics", ownerDocument) instanceof MathMLSemanticsElement);
629            // Assert
630            // .assertTrue(MathElementFactory.elementFromName(
631            // "annotation-xml", aMap) instanceof
632            // MathMLXMLAnnotationElement);
633            // Assert.assertTrue(MathElementFactory.elementFromName("integers",
634            // aMap) instanceof MathMLPredefinedSymbol);
635            // Assert.assertTrue(MathElementFactory.elementFromName("reals", aMap,
636            // base) instanceof MathMLPredefinedSymbol);
637            // Assert.assertTrue(MathElementFactory.elementFromName("rationals",
638            // aMap) instanceof MathMLPredefinedSymbol);
639            // Assert
640            // .assertTrue(MathElementFactory.elementFromName(
641            // "naturalnumbers", aMap) instanceof MathMLPredefinedSymbol);
642            // Assert.assertTrue(MathElementFactory.elementFromName("complexes",
643            // aMap) instanceof MathMLPredefinedSymbol);
644            // Assert.assertTrue(MathElementFactory.elementFromName("primes",
645            // aMap,
646            // base) instanceof MathMLPredefinedSymbol);
647            // Assert.assertTrue(MathElementFactory.elementFromName("exponentiale",
648            // aMap) instanceof MathMLPredefinedSymbol);
649            // Assert.assertTrue(MathElementFactory.elementFromName("imaginaryi",
650            // aMap) instanceof MathMLPredefinedSymbol);
651            // Assert.assertTrue(MathElementFactory.elementFromName("notanumber",
652            // aMap) instanceof MathMLPredefinedSymbol);
653            // Assert.assertTrue(MathElementFactory.elementFromName("true", aMap,
654            // base) instanceof MathMLPredefinedSymbol);
655            // Assert.assertTrue(MathElementFactory.elementFromName("false", aMap,
656            // base) instanceof MathMLPredefinedSymbol);
657            // Assert.assertTrue(MathElementFactory.elementFromName("emptyset",
658            // aMap) instanceof MathMLPredefinedSymbol);
659            // Assert
660            // .assertTrue(MathElementFactory.elementFromName("pi", aMap,
661            // base) instanceof MathMLPredefinedSymbol);
662            // Assert.assertTrue(MathElementFactory.elementFromName("eulergamma",
663            // aMap) instanceof MathMLPredefinedSymbol);
664            // Assert.assertTrue(MathElementFactory.elementFromName("infinity",
665            // aMap) instanceof MathMLPredefinedSymbol);
666    
667        }
668    
669        /**
670         * Misc tests on {@link Mfrac}.
671         *
672         * @throws Exception
673         *             if the test fails.
674         */
675        @Test
676        public void testFrac() throws Exception {
677            final Document d = new DocumentElement();
678            final MathMLFractionElement mfrac = (MathMLFractionElement) d
679                    .createElement(Mfrac.ELEMENT);
680            final Mi mi = (Mi) d.createElement(Mi.ELEMENT);
681            final Mrow mrow = (Mrow) d.createElement(Mrow.ELEMENT);
682            final Mi mi2 = (Mi) d.createElement(Mi.ELEMENT);
683            mfrac.setDenominator(mi);
684            mfrac.setNumerator(mrow);
685            Assert.assertEquals(mi, mfrac.getDenominator());
686            Assert.assertEquals(mrow, mfrac.getNumerator());
687            Assert.assertEquals(mfrac.getChildNodes().getLength(), 2);
688            mfrac.setNumerator(mi2);
689            Assert.assertEquals(mi, mfrac.getDenominator());
690            Assert.assertEquals(mi2, mfrac.getNumerator());
691            Assert.assertEquals(mfrac.getChildNodes().getLength(), 2);
692        }
693    
694        /**
695         * Misc tests on {@link Mmultiscripts}.
696         *
697         * @throws Exception
698         *             if the test fails.
699         */
700        @Test
701        public void testMMultiScripts() throws Exception {
702            final Document doc = MathMLParserSupport
703                    .parseString("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><math mode=\"display\">"
704                            + "<mmultiscripts>"
705                            + "<mo>x</mo>"
706                            + "<mi>a</mi>"
707                            + "<mi>b</mi>"
708                            + "<mprescripts/>"
709                            + "<mi>c</mi>"
710                            + "<mi>d</mi>" + "</mmultiscripts>" + "</math>");
711            final MathMLDocument docElement = DOMBuilder.getInstance()
712                    .createJeuclidDom(doc);
713            final MathMLMathElement mathElement = (MathMLMathElement) docElement
714                    .getFirstChild();
715    
716            final MathMLMultiScriptsElement multi = (MathMLMultiScriptsElement) mathElement
717                    .getChildNodes().item(0);
718    
719            Assert.assertEquals(multi.getBase().getTextContent(), "x");
720            Assert.assertEquals(multi.getSubScript(1).getTextContent(), "a");
721            Assert.assertEquals(multi.getSuperScript(1).getTextContent(), "b");
722            Assert.assertEquals(multi.getPreSubScript(1).getTextContent(), "c");
723            Assert.assertEquals(multi.getPreSuperScript(1).getTextContent(), "d");
724            Assert.assertEquals(multi.getNumprescriptcolumns(), 1);
725            Assert.assertEquals(multi.getNumscriptcolumns(), 1);
726            final Mi mi = (Mi) docElement.createElement(Mi.ELEMENT);
727            multi.insertPreSubScriptBefore(0, mi);
728            Assert.assertEquals(multi.getNumprescriptcolumns(), 2);
729            Assert.assertEquals(multi.getChildNodes().getLength(), 8);
730        }
731    
732        /**
733         * More tests on {@link Mmultiscripts}.
734         *
735         * @throws Exception
736         *             if the test fails.
737         */
738        @Test
739        public void testMMultiScripts2() throws Exception {
740            final Document doc = MathMLParserSupport
741                    .parseString("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><math mode=\"display\">"
742                            + "<mmultiscripts>" + "</mmultiscripts>" + "</math>");
743            final MathMLDocument docElement = DOMBuilder.getInstance()
744                    .createJeuclidDom(doc);
745            final MathMLMathElement mathElement = (MathMLMathElement) docElement
746                    .getFirstChild();
747            final MathMLMultiScriptsElement multi = (MathMLMultiScriptsElement) mathElement
748                    .getChildNodes().item(0);
749            multi.setSubScriptAt(1, (MathMLElement) docElement
750                    .createElement(Mi.ELEMENT));
751            Assert.assertEquals(multi.getChildNodes().getLength(), 3);
752            multi.setSuperScriptAt(1, (MathMLElement) docElement
753                    .createElement(Mi.ELEMENT));
754            Assert.assertEquals(multi.getChildNodes().getLength(), 3);
755            multi.insertPreSuperScriptBefore(0, (MathMLElement) docElement
756                    .createElement(Mi.ELEMENT));
757            Assert.assertEquals(multi.getChildNodes().getLength(), 6);
758            multi.insertPreSubScriptBefore(0, (Mi) docElement
759                    .createElement(Mi.ELEMENT));
760            Assert.assertEquals(multi.getChildNodes().getLength(), 8);
761    
762            Assert.assertNull(multi.getSubScript(0));
763            Assert.assertNull(multi.getSuperScript(0));
764            Assert.assertNull(multi.getSubScript(20));
765            Assert.assertNull(multi.getSuperScript(20));
766        }
767    
768        /**
769         * Test DOM Events.
770         *
771         * @throws Exception
772         *             if the test fails.
773         */
774        @Test
775        public void testEvents() throws Exception {
776            final Document doc = MathMLParserSupport
777                    .parseString("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><math mode=\"display\">"
778                            + "<mi>x</mi>" + "</math>");
779            final MathMLDocument docElement = DOMBuilder.getInstance()
780                    .createJeuclidDom(doc);
781            final MathMLMathElement mathElement = (MathMLMathElement) docElement
782                    .getFirstChild();
783    
784            final MathMLElement mi = (MathMLElement) mathElement.getChildNodes()
785                    .item(0);
786    
787            this.docCount = 0;
788            this.mathCount = 0;
789            this.miCount = 0;
790    
791            ((EventTarget) mathElement).addEventListener("DOMSubtreeModified",
792                    new EventListener() {
793    
794                        public void handleEvent(final Event evt) {
795                            DOMModelTest.this.mathCount++;
796                        }
797                    }, false);
798    
799            ((EventTarget) mi).addEventListener("DOMSubtreeModified",
800                    new EventListener() {
801    
802                        public void handleEvent(final Event evt) {
803                            DOMModelTest.this.miCount++;
804    
805                        }
806                    }, false);
807            ((EventTarget) docElement).addEventListener("DOMSubtreeModified",
808                    new EventListener() {
809    
810                        public void handleEvent(final Event evt) {
811                            DOMModelTest.this.docCount++;
812                        }
813                    }, false);
814            mathElement.appendChild(docElement.createElement(Mi.ELEMENT));
815            Assert.assertTrue("Event must not be called on Mi", this.miCount == 0);
816            Assert.assertTrue("Event must be called on Math", this.mathCount > 0);
817            Assert.assertTrue("Event must be called on Document", this.docCount > 0);
818        }
819    
820        /**
821         * Test getSup/getSuper on sub, sup, and subsuper.
822         *
823         * @throws Exception
824         *             if the test fails.
825         */
826        @Test
827        public void testBadSupSuper() throws Exception {
828            final Document ownerDocument = new DocumentElement();
829    
830            final MathMLScriptElement msup = (MathMLScriptElement) ownerDocument
831                    .createElement(Msup.ELEMENT);
832            final MathMLScriptElement msubsup = (MathMLScriptElement) ownerDocument
833                    .createElement(Msubsup.ELEMENT);
834            final MathMLScriptElement msub = (MathMLScriptElement) ownerDocument
835                    .createElement(Msub.ELEMENT);
836            msup.getSuperscript();
837            msup.getSubscript();
838            msub.getSuperscript();
839            msub.getSubscript();
840            msubsup.getSuperscript();
841            msubsup.getSubscript();
842        }
843    
844        private void testImpl(final Class<?> whichClass) throws Exception {
845            final String name = whichClass.getName();
846            final Method[] methods = whichClass.getDeclaredMethods();
847            final Set<String> names = new TreeSet<String>();
848            for (final Method m : methods) {
849                names.add(m.getName());
850            }
851            Assert.assertTrue(name + " must override newNode",
852                    names.contains("newNode"));
853            Assert.assertFalse(name + " must not override getTagName",
854                    names.contains("getTagName"));
855            Assert.assertTrue(name + " must be final",
856                    Modifier.isFinal(whichClass.getModifiers()));
857    
858        }
859    
860        /**
861         * Test implementation of all presentation elements.
862         *
863         * @throws Exception
864         *             if the test fails.
865         */
866        @Test
867        public void testProperImplementation() throws Exception {
868            this.testImpl(MathImpl.class);
869            this.testImpl(Mfenced.class);
870            this.testImpl(Mfrac.class);
871            this.testImpl(Menclose.class);
872            this.testImpl(Mphantom.class);
873            this.testImpl(Msup.class);
874            this.testImpl(Msub.class);
875            this.testImpl(Mmultiscripts.class);
876            this.testImpl(Mprescripts.class);
877            this.testImpl(None.class);
878            this.testImpl(Msubsup.class);
879            this.testImpl(Munder.class);
880            this.testImpl(Mover.class);
881            this.testImpl(Munderover.class);
882            this.testImpl(Mspace.class);
883            this.testImpl(Ms.class);
884            this.testImpl(Mstyle.class);
885            this.testImpl(Msqrt.class);
886            this.testImpl(Mroot.class);
887            this.testImpl(Mtable.class);
888            this.testImpl(Mtr.class);
889            this.testImpl(Mlabeledtr.class);
890            this.testImpl(Mtd.class);
891            this.testImpl(Mo.class);
892            this.testImpl(Mi.class);
893            this.testImpl(Mn.class);
894            this.testImpl(Mtext.class);
895            this.testImpl(Mrow.class);
896            this.testImpl(Maligngroup.class);
897            this.testImpl(Malignmark.class);
898            this.testImpl(Semantics.class);
899            this.testImpl(Annotation.class);
900            this.testImpl(Mpadded.class);
901            this.testImpl(Merror.class);
902            this.testImpl(Maction.class);
903            this.testImpl(Mglyph.class);
904        }
905    }