| 1 | package org.axdt.axdoc.model.coffeetime; |
|---|
| 2 | |
|---|
| 3 | import java.util.List; |
|---|
| 4 | |
|---|
| 5 | import javax.xml.xpath.XPathExpression; |
|---|
| 6 | import javax.xml.xpath.XPathExpressionException; |
|---|
| 7 | |
|---|
| 8 | import junit.framework.TestCase; |
|---|
| 9 | |
|---|
| 10 | import org.axdt.axdoc.TestConstants; |
|---|
| 11 | import org.axdt.axdoc.model.AXEntry; |
|---|
| 12 | import org.axdt.axdoc.model.AXLevel; |
|---|
| 13 | import org.axdt.axdoc.model.AXRoot; |
|---|
| 14 | import org.axdt.axdoc.model.util.AXUtil; |
|---|
| 15 | import org.axdt.axdoc.util.AXDocParser; |
|---|
| 16 | import org.axdt.axdoc.util.HtmlLoader; |
|---|
| 17 | import org.w3c.dom.Node; |
|---|
| 18 | |
|---|
| 19 | /** |
|---|
| 20 | * This test is just to assert my current assumptions |
|---|
| 21 | * about the structure of asdoc html documents. |
|---|
| 22 | * @author mb0 |
|---|
| 23 | * |
|---|
| 24 | */ |
|---|
| 25 | public class ASDocFormatTest extends TestCase implements TestConstants { |
|---|
| 26 | HtmlLoader loader; |
|---|
| 27 | XPathExpression findMain; |
|---|
| 28 | XPathExpression findtable; |
|---|
| 29 | XPathExpression findtd; |
|---|
| 30 | XPathExpression findDetails; |
|---|
| 31 | XPathExpression findDetailType; |
|---|
| 32 | |
|---|
| 33 | public ASDocFormatTest() { |
|---|
| 34 | loader = new HtmlLoader(); |
|---|
| 35 | try { |
|---|
| 36 | findMain = loader.xpPath.compile("//html:div[@class='MainContent']"); |
|---|
| 37 | findtable = loader.xpPath.compile("./html:table[@class='classHeaderTable']"); |
|---|
| 38 | findtd = loader.xpPath.compile(".//html:tr/html:td[1]"); |
|---|
| 39 | findDetails = loader.xpPath.compile("./html:div[@class='detailBody']"); |
|---|
| 40 | findDetailType = loader.xpPath.compile(".//html:td[@class='detailHeaderType']"); |
|---|
| 41 | } catch (XPathExpressionException e) { |
|---|
| 42 | e.printStackTrace(); |
|---|
| 43 | } |
|---|
| 44 | } |
|---|
| 45 | public void testTypeMembersLocal() throws Exception { |
|---|
| 46 | parserTypeMembers(dataFolder+"axtest/"); |
|---|
| 47 | } |
|---|
| 48 | public void testTypeMembersLangref() throws Exception { |
|---|
| 49 | parserTypeMembers(dataFolder+"asdoc/"); |
|---|
| 50 | } |
|---|
| 51 | private void parserTypeMembers(String url) throws Exception { |
|---|
| 52 | AXDocParser parser = new AXDocParser(); |
|---|
| 53 | // you can specify the documentation url |
|---|
| 54 | AXRoot doc = parser.parse(url, AXLevel.TYPE, "base"); |
|---|
| 55 | List<AXEntry> typeList = AXUtil.getAllTypes(doc); |
|---|
| 56 | for (AXEntry typeNode:typeList) { |
|---|
| 57 | parseType(typeNode); |
|---|
| 58 | } |
|---|
| 59 | } |
|---|
| 60 | String nodeCode; |
|---|
| 61 | private void parseType(AXEntry typeNode) throws Exception { |
|---|
| 62 | Node html = loader.load(typeNode.fullUrl()); |
|---|
| 63 | Node[] contentDivs = loader.eIter(findMain, html); |
|---|
| 64 | assertEquals(typeNode.getName(),2, contentDivs.length); |
|---|
| 65 | Node[] headers = loader.eIter(findtable, contentDivs[0]); |
|---|
| 66 | assertEquals(1, headers.length); |
|---|
| 67 | Node[] headerInfos = loader.eIter(findtd, headers[0]); |
|---|
| 68 | assertEquals(typeNode.toString(),true, headerInfos.length>1); |
|---|
| 69 | assertEquals(typeNode.toString(),true, headerInfos.length<6); |
|---|
| 70 | Node[] detailBodies = loader.eIter(findDetails, contentDivs[1]); |
|---|
| 71 | // cannot be null but can be empty .. |
|---|
| 72 | assertNotNull(detailBodies); |
|---|
| 73 | nodeCode = "|start|"; |
|---|
| 74 | for (Node node : detailBodies) { |
|---|
| 75 | // ignore empty detailBody |
|---|
| 76 | if (!node.hasChildNodes()) continue; |
|---|
| 77 | checkNode(typeNode,node); |
|---|
| 78 | } |
|---|
| 79 | } |
|---|
| 80 | private String getHeader(Node node) throws Exception { |
|---|
| 81 | Node header = node.getPreviousSibling(); |
|---|
| 82 | if (header.getNodeName().equals("br")) { |
|---|
| 83 | // some examples have a br between detail body and header |
|---|
| 84 | header = header.getPreviousSibling(); |
|---|
| 85 | } |
|---|
| 86 | // TODO Examples, have we any uses for these ? |
|---|
| 87 | if (header.getNodeName().equals("div")) { |
|---|
| 88 | assertEquals("exampleHeader", header.getAttributes().getNamedItem("class").getNodeValue()); |
|---|
| 89 | return "Example"; |
|---|
| 90 | } |
|---|
| 91 | // find header |
|---|
| 92 | assertEquals("table", header.getNodeName()); |
|---|
| 93 | // any other element should have a header table |
|---|
| 94 | Node headerTypeNode = loader.eval(findDetailType, header); |
|---|
| 95 | assertNotNull(nodeCode, headerTypeNode); |
|---|
| 96 | return headerTypeNode.getTextContent().trim(); |
|---|
| 97 | } |
|---|
| 98 | private void checkNode(AXEntry typeNode, Node node) throws Exception { |
|---|
| 99 | Node next = node.getFirstChild(); |
|---|
| 100 | assertNotNull("detail should have at least two children",next.getNextSibling()); |
|---|
| 101 | String headerType = getHeader(node); |
|---|
| 102 | boolean isExample = headerType.equals("Example"); |
|---|
| 103 | boolean isEvent = headerType.equals("Event"); |
|---|
| 104 | boolean isConstructor = headerType.equals("Constructor"); |
|---|
| 105 | boolean isMethod = headerType.equals("method"); |
|---|
| 106 | boolean isProperty = headerType.equals("property"); |
|---|
| 107 | boolean isConstant = headerType.equals("Constant"); |
|---|
| 108 | // headerType should be one of the expected |
|---|
| 109 | assertTrue(isExample||isEvent||isConstructor||isMethod||isProperty||isConstant); |
|---|
| 110 | // we dont care about examples |
|---|
| 111 | if (isExample) return; |
|---|
| 112 | // TODO Event |
|---|
| 113 | if (isEvent) return; |
|---|
| 114 | |
|---|
| 115 | // the rest should be members. |
|---|
| 116 | // first child is code with declaration |
|---|
| 117 | assertEquals("after "+nodeCode,"code", next.getNodeName()); |
|---|
| 118 | nodeCode = next.getTextContent().trim(); |
|---|
| 119 | next = next.getNextSibling(); |
|---|
| 120 | // when text node it is a property with getter and/or setter |
|---|
| 121 | if (next.getNodeType()==Node.TEXT_NODE) { |
|---|
| 122 | assertTrue(isProperty); |
|---|
| 123 | String textContent = next.getTextContent().replaceAll("[^\\w-]", ""); |
|---|
| 124 | assertEquals(true, |
|---|
| 125 | textContent.equals("read-only") |
|---|
| 126 | || textContent.equals("write-only") |
|---|
| 127 | || textContent.equals("read-write") |
|---|
| 128 | ); |
|---|
| 129 | next = next.getNextSibling(); |
|---|
| 130 | } |
|---|
| 131 | // might have a deprecated div |
|---|
| 132 | if (next.getNodeName().equals("div")) { |
|---|
| 133 | assertTrue(nodeCode, next.getTextContent().contains("Deprecated")); |
|---|
| 134 | next = next.getNextSibling(); |
|---|
| 135 | } |
|---|
| 136 | // at least one empty paragraph should follow |
|---|
| 137 | assertEquals(nodeCode,"p", next.getNodeName()); |
|---|
| 138 | assertEquals(nodeCode,false, next.hasChildNodes()); |
|---|
| 139 | // consume empty p and following empty brs |
|---|
| 140 | do { |
|---|
| 141 | next = next.getNextSibling(); |
|---|
| 142 | } while (next != null && "br".equals(next.getNodeName())); |
|---|
| 143 | while (next!=null && next.getNodeName().equals("table")) { |
|---|
| 144 | assertEquals(1,next.getChildNodes().getLength()); |
|---|
| 145 | assertEquals(2,next.getFirstChild().getChildNodes().getLength()); |
|---|
| 146 | next = next.getNextSibling(); |
|---|
| 147 | } |
|---|
| 148 | while (next!=null && !next.hasChildNodes()&&(next.getTextContent().equals("")||next.getNodeType()==Node.TEXT_NODE)) { |
|---|
| 149 | if (next.getNodeType() == Node.TEXT_NODE) { |
|---|
| 150 | assertEquals(nodeCode,"", next.getTextContent().trim()); |
|---|
| 151 | } else { |
|---|
| 152 | assertEquals(nodeCode,true, next.getNodeName().equals("p")||next.getNodeName().equals("br")); |
|---|
| 153 | } |
|---|
| 154 | next = next.getNextSibling(); |
|---|
| 155 | } |
|---|
| 156 | if (next == null) { |
|---|
| 157 | // it might be the last now already |
|---|
| 158 | return; |
|---|
| 159 | } |
|---|
| 160 | while ("p".equals(next.getNodeName()) |
|---|
| 161 | ||("table".equals(next.getNodeName()) && next.hasAttributes()) |
|---|
| 162 | ||"ul".equals(next.getNodeName()) |
|---|
| 163 | ||"ol".equals(next.getNodeName()) |
|---|
| 164 | ||"pre".equals(next.getNodeName()) |
|---|
| 165 | ||"code".equals(next.getNodeName()) |
|---|
| 166 | ||"b".equals(next.getNodeName()) |
|---|
| 167 | ||("span".equals(next.getNodeName())&&!next.hasAttributes()) |
|---|
| 168 | ||"div".equals(next.getNodeName())) { |
|---|
| 169 | if ("p".equals(next.getNodeName()) && next.hasChildNodes()) { |
|---|
| 170 | Node firstChild = next.getFirstChild(); |
|---|
| 171 | if (firstChild.getNodeName().equals("span")) { |
|---|
| 172 | Node namedItem = firstChild.getAttributes().getNamedItem("class"); |
|---|
| 173 | if (namedItem != null && namedItem.getNodeValue().equals("label")) |
|---|
| 174 | break; |
|---|
| 175 | } |
|---|
| 176 | } |
|---|
| 177 | if ("table".equals(next.getNodeName())) { |
|---|
| 178 | Node item = next.getAttributes().getNamedItem("class"); |
|---|
| 179 | // Matrix or BitmapData scale9grid |
|---|
| 180 | assertEquals(nodeCode,true, item.getNodeValue().equals("innertable") || item.getNodeValue().equals("+ topic/table adobe-d/adobetable")); |
|---|
| 181 | if (item == null || !(item.getNodeValue().equals("innertable") || item.getNodeValue().equals("+ topic/table adobe-d/adobetable"))) |
|---|
| 182 | break; |
|---|
| 183 | } |
|---|
| 184 | assertNotNull(next.getTextContent()); |
|---|
| 185 | do { |
|---|
| 186 | next = next.getNextSibling(); |
|---|
| 187 | } while (next != null && next.getNodeType() == Node.TEXT_NODE); |
|---|
| 188 | if (next == null) return; |
|---|
| 189 | } |
|---|
| 190 | while (next.getNodeName() == "br") { |
|---|
| 191 | next = next.getNextSibling(); |
|---|
| 192 | } |
|---|
| 193 | String spanTitle; |
|---|
| 194 | if (next.getNodeName() == "p") { |
|---|
| 195 | assertEquals(nodeCode+" "+next.getFirstChild().getNodeValue(),"span", next.getFirstChild().getNodeName()); |
|---|
| 196 | spanTitle = next.getFirstChild().getTextContent().trim(); |
|---|
| 197 | } else { |
|---|
| 198 | assertEquals(nodeCode,"span",next.getNodeName()); |
|---|
| 199 | spanTitle = next.getTextContent().trim(); |
|---|
| 200 | } |
|---|
| 201 | assertEquals(nodeCode+" "+spanTitle,true |
|---|
| 202 | ,"Implementation".equals(spanTitle) |
|---|
| 203 | ||"Example".equals(spanTitle) |
|---|
| 204 | ||"Throws".equals(spanTitle) |
|---|
| 205 | ||"Events".equals(spanTitle) |
|---|
| 206 | ||"Returns".equals(spanTitle) |
|---|
| 207 | ||"See also".equals(spanTitle) |
|---|
| 208 | ||"Parameters".equals(spanTitle) |
|---|
| 209 | ); |
|---|
| 210 | } |
|---|
| 211 | } |
|---|