1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.xpath;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.utils.XpathUtil.getXpathItems;
24
25 import java.io.File;
26 import java.util.List;
27
28 import org.junit.jupiter.api.BeforeEach;
29 import org.junit.jupiter.api.Test;
30
31 import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport;
32 import com.puppycrawl.tools.checkstyle.DetailAstImpl;
33 import com.puppycrawl.tools.checkstyle.JavaParser;
34 import com.puppycrawl.tools.checkstyle.api.DetailAST;
35 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
36 import com.puppycrawl.tools.checkstyle.xpath.iterators.DescendantIterator;
37 import net.sf.saxon.om.AxisInfo;
38 import net.sf.saxon.om.NamespaceUri;
39 import net.sf.saxon.om.NodeInfo;
40 import net.sf.saxon.tree.iter.ArrayIterator;
41 import net.sf.saxon.tree.iter.AxisIterator;
42 import net.sf.saxon.tree.iter.EmptyIterator;
43
44 public class ElementNodeTest extends AbstractPathTestSupport {
45
46 private static RootNode rootNode;
47
48 @Override
49 protected String getPackageLocation() {
50 return "com/puppycrawl/tools/checkstyle/xpath/xpathmapper";
51 }
52
53 @BeforeEach
54 public void init() throws Exception {
55 final File file = new File(getPath("InputXpathMapperAst.java"));
56 final DetailAST rootAst = JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS);
57 rootNode = new RootNode(rootAst);
58 }
59
60 @Test
61 public void testParentChildOrdering() {
62 final DetailAstImpl detailAST = new DetailAstImpl();
63 detailAST.setType(TokenTypes.VARIABLE_DEF);
64
65 final DetailAstImpl parentAST = new DetailAstImpl();
66 parentAST.setFirstChild(detailAST);
67 parentAST.setType(TokenTypes.METHOD_DEF);
68
69 final AbstractNode parentNode = new ElementNode(rootNode, rootNode, parentAST, 1, 0);
70 final AbstractNode childNode = new ElementNode(rootNode, parentNode, detailAST, 2, 0);
71 assertWithMessage("Incorrect ordering value")
72 .that(parentNode.compareOrder(childNode))
73 .isEqualTo(-1);
74 assertWithMessage("Incorrect ordering value")
75 .that(childNode.compareOrder(parentNode))
76 .isEqualTo(1);
77 }
78
79 @Test
80 public void testSiblingsOrdering() {
81 final DetailAstImpl detailAst1 = new DetailAstImpl();
82 detailAst1.setType(TokenTypes.VARIABLE_DEF);
83
84 final DetailAstImpl detailAst2 = new DetailAstImpl();
85 detailAst2.setType(TokenTypes.NUM_INT);
86
87 final DetailAstImpl parentAST = new DetailAstImpl();
88 parentAST.setType(TokenTypes.METHOD_DEF);
89 parentAST.addChild(detailAst1);
90 parentAST.addChild(detailAst2);
91
92 final AbstractNode parentNode = new ElementNode(rootNode, rootNode, parentAST, 1, 0);
93 final List<AbstractNode> children = parentNode.getChildren();
94
95 assertWithMessage("Incorrect ordering value")
96 .that(children.get(0).compareOrder(children.get(1)))
97 .isEqualTo(-1);
98 assertWithMessage("Incorrect ordering value")
99 .that(children.get(1).compareOrder(children.get(0)))
100 .isEqualTo(1);
101 }
102
103 @Test
104 public void testCompareOrderWrongInstance() throws Exception {
105 final String xpath = "//OBJBLOCK";
106 final List<NodeInfo> nodes = getXpathItems(xpath, rootNode);
107 final int result = nodes.get(0).compareOrder(null);
108 assertWithMessage("Expected result wrong")
109 .that(result)
110 .isEqualTo(0);
111 }
112
113 @Test
114 public void testGetParent() throws Exception {
115 final String xpath = "//OBJBLOCK";
116 final List<NodeInfo> nodes = getXpathItems(xpath, rootNode);
117 assertWithMessage("Invalid number of nodes")
118 .that(nodes)
119 .hasSize(1);
120 final AbstractNode parent = (AbstractNode) nodes.get(0).getParent();
121 assertWithMessage("Invalid token type")
122 .that(parent.getTokenType())
123 .isEqualTo(TokenTypes.CLASS_DEF);
124 }
125
126 @Test
127 public void testRootOfElementNode() throws Exception {
128 final String xpath = "//OBJBLOCK";
129 final List<NodeInfo> nodes = getXpathItems(xpath, rootNode);
130 assertWithMessage("Invalid number of nodes")
131 .that(nodes)
132 .hasSize(1);
133 final AbstractNode root = (AbstractNode) nodes.get(0).getRoot();
134 assertWithMessage("Invalid token type")
135 .that(root.getTokenType())
136 .isEqualTo(TokenTypes.COMPILATION_UNIT);
137 assertWithMessage("Should return true, because selected node is RootNode")
138 .that(root)
139 .isInstanceOf(RootNode.class);
140 }
141
142 @Test
143 public void testGetNodeByValueNumInt() throws Exception {
144 final String xPath = "//NUM_INT[@text = 123]";
145 final List<NodeInfo> nodes = getXpathItems(xPath, rootNode);
146 assertWithMessage("Invalid number of nodes")
147 .that(nodes)
148 .hasSize(1);
149 final int tokenType = ((AbstractNode) nodes.get(0)).getTokenType();
150 assertWithMessage("Invalid token type")
151 .that(tokenType)
152 .isEqualTo(TokenTypes.NUM_INT);
153 }
154
155 @Test
156 public void testGetNodeByValueStringLiteral() throws Exception {
157 final String xPath = "//STRING_LITERAL[@text = 'HelloWorld']";
158 final List<NodeInfo> nodes = getXpathItems(xPath, rootNode);
159 assertWithMessage("Invalid number of nodes")
160 .that(nodes)
161 .hasSize(2);
162 final int tokenType = ((AbstractNode) nodes.get(0)).getTokenType();
163 assertWithMessage("Invalid token type")
164 .that(tokenType)
165 .isEqualTo(TokenTypes.STRING_LITERAL);
166 }
167
168 @Test
169 public void testGetNodeByValueWithSameTokenText() throws Exception {
170 final String xPath = "//MODIFIERS[@text = 'MODIFIERS']";
171 final List<NodeInfo> nodes = getXpathItems(xPath, rootNode);
172 assertWithMessage("Invalid number of nodes")
173 .that(nodes)
174 .hasSize(0);
175 }
176
177 @Test
178 public void testGetAttributeValue() {
179 final DetailAstImpl detailAST = new DetailAstImpl();
180 detailAST.setType(TokenTypes.IDENT);
181 detailAST.setText("HelloWorld");
182
183 final ElementNode elementNode = new ElementNode(rootNode, rootNode, detailAST, 1, 0);
184
185 assertWithMessage("Invalid text attribute")
186 .that(elementNode.getAttributeValue((NamespaceUri) null, "text"))
187 .isEqualTo("HelloWorld");
188 }
189
190 @Test
191 public void testGetAttributeCached() {
192 final DetailAstImpl detailAST = new DetailAstImpl();
193 detailAST.setType(TokenTypes.IDENT);
194 detailAST.setText("HelloWorld");
195
196 final ElementNode elementNode = new ElementNode(rootNode, rootNode, detailAST, 1, 0);
197 try (AxisIterator first = elementNode.iterateAxis(AxisInfo.ATTRIBUTE);
198 AxisIterator second = elementNode.iterateAxis(AxisInfo.ATTRIBUTE)) {
199 assertWithMessage("Expected same attribute node")
200 .that(second.next())
201 .isSameInstanceAs(first.next());
202 }
203 }
204
205 @Test
206 public void testGetAttributeValueNoAttribute() {
207 final DetailAstImpl detailAST = new DetailAstImpl();
208 detailAST.setType(TokenTypes.CLASS_DEF);
209 detailAST.setText("HelloWorld");
210
211 final ElementNode elementNode = new ElementNode(rootNode, rootNode, detailAST, 1, 0);
212
213 assertWithMessage("Must be null")
214 .that(elementNode.getAttributeValue((NamespaceUri) null, "text"))
215 .isNull();
216 }
217
218 @Test
219 public void testGetAttributeValueWrongAttribute() {
220 final DetailAstImpl detailAST = new DetailAstImpl();
221 detailAST.setType(TokenTypes.IDENT);
222 detailAST.setText("HelloWorld");
223
224 final ElementNode elementNode = new ElementNode(rootNode, rootNode, detailAST, 1, 0);
225
226 assertWithMessage("Must be null")
227 .that(elementNode.getAttributeValue((NamespaceUri) null, "somename"))
228 .isNull();
229 }
230
231 @Test
232 public void testIterateAxisEmptyChildren() {
233 final DetailAstImpl detailAST = new DetailAstImpl();
234 detailAST.setType(TokenTypes.METHOD_DEF);
235 final ElementNode elementNode = new ElementNode(rootNode, rootNode, detailAST, 1, 0);
236 try (AxisIterator iterator = elementNode.iterateAxis(AxisInfo.CHILD)) {
237 assertWithMessage("Invalid iterator")
238 .that(iterator)
239 .isInstanceOf(EmptyIterator.class);
240 }
241 try (AxisIterator iterator = elementNode.iterateAxis(AxisInfo.DESCENDANT)) {
242 assertWithMessage("Invalid iterator")
243 .that(iterator)
244 .isInstanceOf(EmptyIterator.class);
245 }
246 }
247
248 @Test
249 public void testIterateAxisWithChildren() {
250 final DetailAstImpl detailAST = new DetailAstImpl();
251 detailAST.setType(TokenTypes.METHOD_DEF);
252 final DetailAstImpl childAst = new DetailAstImpl();
253 childAst.setType(TokenTypes.VARIABLE_DEF);
254 detailAST.addChild(childAst);
255 final ElementNode elementNode = new ElementNode(rootNode, rootNode, detailAST, 1, 0);
256 try (AxisIterator iterator = elementNode.iterateAxis(AxisInfo.CHILD)) {
257 assertWithMessage("Invalid iterator")
258 .that(iterator)
259 .isInstanceOf(ArrayIterator.class);
260 }
261 try (AxisIterator iterator = elementNode.iterateAxis(AxisInfo.DESCENDANT)) {
262 assertWithMessage("Invalid iterator")
263 .that(iterator)
264 .isInstanceOf(DescendantIterator.class);
265 }
266 }
267
268 @Test
269 public void testIterateAxisWithNoSiblings() {
270 final DetailAstImpl detailAST = new DetailAstImpl();
271 detailAST.setType(TokenTypes.VARIABLE_DEF);
272
273 final DetailAstImpl parentAST = new DetailAstImpl();
274 parentAST.setFirstChild(detailAST);
275 parentAST.setType(TokenTypes.METHOD_DEF);
276 final AbstractNode parentNode = new ElementNode(rootNode, rootNode, parentAST, 1, 0);
277
278 final AbstractNode elementNode = parentNode.getChildren().get(0);
279 try (AxisIterator iterator = elementNode.iterateAxis(AxisInfo.FOLLOWING_SIBLING)) {
280 assertWithMessage("Invalid iterator")
281 .that(iterator)
282 .isInstanceOf(EmptyIterator.class);
283 }
284 try (AxisIterator iterator = elementNode.iterateAxis(AxisInfo.PRECEDING_SIBLING)) {
285 assertWithMessage("Invalid iterator")
286 .that(iterator)
287 .isInstanceOf(EmptyIterator.class);
288 }
289 }
290 }