001 /* 002 * Copyright 2002 - 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: LayoutTest.java,v 92b6a7c39d7f 2010/08/11 20:23:17 max $ */ 018 019 package net.sourceforge.jeuclid.test; 020 021 import java.util.List; 022 023 import net.sourceforge.jeuclid.DOMBuilder; 024 import net.sourceforge.jeuclid.MathMLParserSupport; 025 import net.sourceforge.jeuclid.elements.presentation.general.Mfrac; 026 import net.sourceforge.jeuclid.elements.presentation.token.Mi; 027 import net.sourceforge.jeuclid.elements.presentation.token.Mn; 028 import net.sourceforge.jeuclid.layout.JEuclidView; 029 import net.sourceforge.jeuclid.layout.LayoutStage; 030 import net.sourceforge.jeuclid.layout.LayoutableNode; 031 032 import org.junit.Assert; 033 import org.junit.Test; 034 import org.w3c.dom.Node; 035 import org.w3c.dom.mathml.MathMLDocument; 036 import org.w3c.dom.mathml.MathMLFractionElement; 037 import org.w3c.dom.mathml.MathMLMathElement; 038 import org.w3c.dom.mathml.MathMLPresentationContainer; 039 import org.w3c.dom.mathml.MathMLPresentationToken; 040 import org.w3c.dom.views.DocumentView; 041 042 /** 043 * @version $Revision: 92b6a7c39d7f $ 044 */ 045 public class LayoutTest { 046 047 /** 048 * Test string with xml header. 049 */ 050 final static public String TEST1 = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><math mode=\"display\">" 051 + "<mrow><mo>(</mo><mn>555</mn></mrow></math>"; 052 053 /** 054 * Test if there is something in the view. 055 * 056 * @throws Exception 057 * if the test fails. 058 */ 059 @Test 060 public void testViewNotEmpty() throws Exception { 061 final MathMLDocument docElement = DOMBuilder.getInstance() 062 .createJeuclidDom( 063 MathMLParserSupport.parseString(LayoutTest.TEST1)); 064 final JEuclidView view = (JEuclidView) (((DocumentView) docElement) 065 .getDefaultView()); 066 Assert.assertTrue( 067 "View has not enough ascent: " + view.getAscentHeight(), 068 view.getAscentHeight() > 1.0f); 069 Assert.assertTrue("View has not enoguh width: " + view.getWidth(), 070 view.getWidth() > 1.0f); 071 Assert.assertTrue("Descent Height < 0: " + view.getDescentHeight(), 072 view.getDescentHeight() >= 0.0f); 073 } 074 075 /** 076 * Tests if view modifies itself when DOM is modified. 077 * 078 * @throws Exception 079 * if the test fails. 080 */ 081 @Test 082 public void testViewMutable() throws Exception { 083 final MathMLDocument docElement = DOMBuilder.getInstance() 084 .createJeuclidDom( 085 MathMLParserSupport.parseString(LayoutTest.TEST1)); 086 final JEuclidView view = (JEuclidView) (((DocumentView) docElement) 087 .getDefaultView()); 088 089 final float oldAscent = view.getAscentHeight(); 090 final float oldWidth = view.getWidth(); 091 092 final MathMLMathElement mathElement = (MathMLMathElement) docElement 093 .getFirstChild(); 094 final MathMLPresentationContainer mrow = (MathMLPresentationContainer) mathElement 095 .getFirstChild(); 096 final LayoutableNode mop = (LayoutableNode) mrow.getFirstChild(); 097 final float oldmopascent = view.getInfo(mop).getAscentHeight( 098 LayoutStage.STAGE2); 099 100 final MathMLFractionElement mfrac = (MathMLFractionElement) docElement 101 .createElement(Mfrac.ELEMENT); 102 103 final MathMLPresentationToken denom = (MathMLPresentationToken) docElement 104 .createElement(Mn.ELEMENT); 105 106 denom.setTextContent("123"); 107 mfrac.setDenominator(denom); 108 final MathMLPresentationToken nom = (MathMLPresentationToken) docElement 109 .createElement(Mi.ELEMENT); 110 nom.setTextContent("X"); 111 mfrac.setNumerator(nom); 112 mrow.appendChild(mfrac); 113 114 Assert.assertTrue("Width of view should increase: " + view.getWidth() 115 + " > " + oldWidth, view.getWidth() > oldWidth); 116 Assert.assertTrue( 117 "Heightof view should increase: " + view.getAscentHeight() 118 + " > " + oldAscent, view.getAscentHeight() > oldAscent); 119 120 final float newmopascent = view.getInfo(mop).getAscentHeight( 121 LayoutStage.STAGE2); 122 Assert.assertTrue("Operator should be larger: " + newmopascent + " > " 123 + oldmopascent, newmopascent > oldmopascent); 124 } 125 126 /** 127 * Test whitespace handling. 128 * 129 * @throws Exception 130 * if the test fails. 131 */ 132 @Test 133 public void testWhitespace() throws Exception { 134 final MathMLDocument docElement = DOMBuilder 135 .getInstance() 136 .createJeuclidDom( 137 MathMLParserSupport 138 .parseString("<math><mtext>x x</mtext><mtext> x x </mtext><mtext>x x</mtext></math>")); 139 final JEuclidView view = (JEuclidView) (((DocumentView) docElement) 140 .getDefaultView()); 141 142 final MathMLMathElement mathElement = (MathMLMathElement) docElement 143 .getFirstChild(); 144 final LayoutableNode m1 = (LayoutableNode) mathElement 145 .getFirstChild(); 146 final LayoutableNode m2 = (LayoutableNode) m1.getNextSibling(); 147 final LayoutableNode m3 = (LayoutableNode) m2.getNextSibling(); 148 149 // To trigger layout 150 view.getWidth(); 151 152 final float w1 = view.getInfo(m1).getWidth(LayoutStage.STAGE2); 153 final float w2 = view.getInfo(m2).getWidth(LayoutStage.STAGE2); 154 final float w3 = view.getInfo(m3).getWidth(LayoutStage.STAGE2); 155 156 Assert.assertEquals("Whitespace around text should be trimmed to none", 157 w2, w1, 0.01); 158 Assert.assertEquals("Whitespace inside text should be trimmed to 1", 159 w3, w1, 0.01); 160 161 } 162 163 /** 164 * Test MO without math parent. 165 * 166 * @throws Exception 167 * if the test fails. 168 */ 169 @Test 170 public void testMoWithoutParent() throws Exception { 171 final MathMLDocument docElement = DOMBuilder 172 .getInstance() 173 .createJeuclidDom( 174 MathMLParserSupport 175 .parseString("<mrow><mo>∑</mo></mrow>")); 176 final JEuclidView view = (JEuclidView) (((DocumentView) docElement) 177 .getDefaultView()); 178 179 // To trigger layout 180 view.getWidth(); 181 } 182 183 /** 184 * Test MO without any parent. 185 * 186 * @throws Exception 187 * if the test fails. 188 */ 189 @Test 190 public void testMoWithoutParent2() throws Exception { 191 final MathMLDocument docElement = DOMBuilder.getInstance() 192 .createJeuclidDom( 193 MathMLParserSupport.parseString("<mo>∑</mo>")); 194 final JEuclidView view = (JEuclidView) (((DocumentView) docElement) 195 .getDefaultView()); 196 197 // To trigger layout 198 view.getWidth(); 199 } 200 201 /** 202 * Test if getNodesAt() works. 203 * 204 * @throws Exception 205 * if the test fails. 206 */ 207 @Test 208 public void testGetNodesAt() throws Exception { 209 final MathMLDocument docElement = DOMBuilder.getInstance() 210 .createJeuclidDom( 211 MathMLParserSupport.parseString(LayoutTest.TEST1)); 212 final JEuclidView view = (JEuclidView) (((DocumentView) docElement) 213 .getDefaultView()); 214 final List<JEuclidView.NodeRect> rlist = view.getNodesAt(15, 0, 0, 0); 215 Assert.assertSame(rlist.get(0).getNode(), docElement); 216 final Node math = docElement.getFirstChild(); 217 Assert.assertSame(rlist.get(1).getNode(), math); 218 final Node mrow = math.getFirstChild(); 219 Assert.assertSame(rlist.get(2).getNode(), mrow); 220 final Node five = mrow.getFirstChild().getNextSibling(); 221 Assert.assertSame(rlist.get(3).getNode(), five); 222 } 223 }