Line 0
Link Here
|
|
|
1 |
/* |
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 2011 Oracle and/or its affiliates. All rights reserved. |
5 |
* |
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates. |
7 |
* Other names may be trademarks of their respective owners. |
8 |
* |
9 |
* The contents of this file are subject to the terms of either the GNU |
10 |
* General Public License Version 2 only ("GPL") or the Common |
11 |
* Development and Distribution License("CDDL") (collectively, the |
12 |
* "License"). You may not use this file except in compliance with the |
13 |
* License. You can obtain a copy of the License at |
14 |
* http://www.netbeans.org/cddl-gplv2.html |
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
16 |
* specific language governing permissions and limitations under the |
17 |
* License. When distributing the software, include this License Header |
18 |
* Notice in each file and include the License file at |
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this |
20 |
* particular file as subject to the "Classpath" exception as provided |
21 |
* by Oracle in the GPL Version 2 section of the License file that |
22 |
* accompanied this code. If applicable, add the following below the |
23 |
* License Header, with the fields enclosed by brackets [] replaced by |
24 |
* your own identifying information: |
25 |
* "Portions Copyrighted [year] [name of copyright owner]" |
26 |
* |
27 |
* If you wish your version of this file to be governed by only the CDDL |
28 |
* or only the GPL Version 2, indicate your decision by adding |
29 |
* "[Contributor] elects to include this software in this distribution |
30 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
31 |
* single choice of license, a recipient has the option to distribute |
32 |
* your version of this file under either the CDDL, the GPL Version 2 or |
33 |
* to extend the choice of license to its licensees as provided above. |
34 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
35 |
* Version 2 license, then the option applies only if the new code is |
36 |
* made subject to such option by the copyright holder. |
37 |
* |
38 |
* Contributor(s): |
39 |
* |
40 |
* Portions Copyrighted 2011 Sun Microsystems, Inc. |
41 |
*/ |
42 |
package org.netbeans.modules.xml.text.completion; |
43 |
|
44 |
import java.lang.reflect.Constructor; |
45 |
import java.net.URL; |
46 |
import javax.swing.Icon; |
47 |
import org.netbeans.junit.NbTestCase; |
48 |
import org.netbeans.junit.NbTestSuite; |
49 |
|
50 |
import org.netbeans.modules.editor.completion.CompletionImpl; |
51 |
import org.netbeans.modules.editor.completion.CompletionResultSetImpl; |
52 |
import org.netbeans.modules.xml.api.EncodingUtil; |
53 |
import org.netbeans.modules.xml.api.model.DescriptionSource; |
54 |
import org.netbeans.modules.xml.api.model.GrammarResult; |
55 |
import org.netbeans.modules.xml.spi.dom.AbstractNode; |
56 |
import org.netbeans.spi.editor.completion.CompletionDocumentation; |
57 |
import org.netbeans.spi.editor.completion.CompletionProvider; |
58 |
import org.netbeans.spi.editor.completion.CompletionResultSet; |
59 |
import org.netbeans.spi.editor.completion.CompletionTask; |
60 |
|
61 |
/** |
62 |
* Checks behaviour of {@link GrammarResult} support in the ElementResultItem. |
63 |
* plain CompletionDocumentation must work unchanged. If mixin interface is implemented, |
64 |
* explicit values (content, resolved links) must take precedence. |
65 |
* <p/> |
66 |
* If contentURL is provided, links must be resolved and content loaded by the |
67 |
* ElementResultItem support even though the supplied CompletionDocumentation itself does not |
68 |
* provide content/links. |
69 |
* |
70 |
* @author sdedic |
71 |
*/ |
72 |
public class ElementResultItemDocumentationTest extends NbTestCase { |
73 |
|
74 |
public static NbTestSuite suite() { |
75 |
NbTestSuite suite = new NbTestSuite(); |
76 |
suite.addTestSuite(ElementResultItemDocumentationTest.class); |
77 |
return suite; |
78 |
} |
79 |
|
80 |
public ElementResultItemDocumentationTest(String name) { |
81 |
super(name); |
82 |
} |
83 |
|
84 |
@Override |
85 |
protected void setUp() throws Exception { |
86 |
super.setUp(); |
87 |
} |
88 |
|
89 |
@Override |
90 |
protected void tearDown() throws Exception { |
91 |
super.tearDown(); |
92 |
} |
93 |
|
94 |
private CompletionResultSetImpl rsImpl; |
95 |
|
96 |
|
97 |
private CompletionResultSet resultSetFor(CompletionTask task, int type) throws Exception { |
98 |
rsImpl = createCompletionResultImpl(task, type); |
99 |
return rsImpl.getResultSet(); |
100 |
} |
101 |
|
102 |
private CompletionResultSetImpl createCompletionResultImpl(CompletionTask task, int type) throws Exception { |
103 |
Class clazz = CompletionResultSetImpl.class; |
104 |
Constructor ctor = clazz.getDeclaredConstructor(CompletionImpl.class, Object.class, CompletionTask.class, Integer.TYPE); |
105 |
ctor.setAccessible(true); |
106 |
return (CompletionResultSetImpl)ctor.newInstance(CompletionImpl.get(), "", task, type); |
107 |
} |
108 |
|
109 |
/** |
110 |
* Check the previou state, result items without the mixin interface. |
111 |
* Should return the description 'as is' |
112 |
* |
113 |
* @throws Exception |
114 |
*/ |
115 |
private static final String PLAIN_DESCRIPTION_TEXT = "Plain description"; |
116 |
|
117 |
public void testPlainContent() throws Exception { |
118 |
MockGrammarResult r = new MockGrammarResult(); |
119 |
|
120 |
r.setDescription(PLAIN_DESCRIPTION_TEXT); |
121 |
ElementResultItem item = new ElementResultItem(0, r); |
122 |
CompletionTask task = item.doCreateDocumentationTask(r); |
123 |
|
124 |
CompletionResultSet rs = resultSetFor(task, CompletionProvider.DOCUMENTATION_QUERY_TYPE); |
125 |
task.query(rs); |
126 |
|
127 |
assertTrue(rs.isFinished()); |
128 |
|
129 |
assertEquals(PLAIN_DESCRIPTION_TEXT, rsImpl.getDocumentation().getText()); |
130 |
|
131 |
// should return null from the url. |
132 |
assertNull(rsImpl.getDocumentation().getURL()); |
133 |
|
134 |
// should not be able to resolve links |
135 |
assertNull(rsImpl.getDocumentation().resolveLink("link")); |
136 |
} |
137 |
|
138 |
private URL createResourceName(String n) { |
139 |
return ElementResultItemDocumentationTest.class.getResource(n); |
140 |
} |
141 |
|
142 |
private CompletionDocumentation createDocResourceResultSet(MockUrlGrammarResult r) throws Exception { |
143 |
if (r == null) { |
144 |
r = new MockUrlGrammarResult(); |
145 |
r.setContentURL(createResourceName("res/docResource.html")); |
146 |
r.setExternal(true); |
147 |
} |
148 |
|
149 |
ElementResultItem item = new ElementResultItem(0, r); |
150 |
CompletionTask task = item.doCreateDocumentationTask(r); |
151 |
CompletionResultSet rs = resultSetFor(task, CompletionProvider.DOCUMENTATION_QUERY_TYPE); |
152 |
task.query(rs); |
153 |
|
154 |
assertTrue(rs.isFinished()); |
155 |
|
156 |
return rsImpl.getDocumentation(); |
157 |
} |
158 |
|
159 |
/** |
160 |
* Checks that custom contents overrides the one supplied by XMLResultItem |
161 |
* |
162 |
* @throws Exception |
163 |
*/ |
164 |
public void testCustomContent() throws Exception { |
165 |
URL res = EncodingUtil.class.getResource("/org/netbeans/modules/xml/core/resources/Bundle.properties"); |
166 |
MockUrlGrammarResult test = new MockUrlGrammarResult(); |
167 |
test.setContentURL(res); |
168 |
test.setExternal(false); |
169 |
test.setDescription(PLAIN_DESCRIPTION_TEXT); |
170 |
|
171 |
CompletionDocumentation doc = createDocResourceResultSet(test); |
172 |
assertNull(doc.getURL()); |
173 |
assertEquals("Invalid content", PLAIN_DESCRIPTION_TEXT, doc.getText()); |
174 |
} |
175 |
|
176 |
/** |
177 |
* Checks documentation bundled in a JAR - not openable by external browser. |
178 |
* Need a resource within a JAR |
179 |
* |
180 |
* @throws Exception |
181 |
*/ |
182 |
public void testInternalUrlDocumentation() throws Exception { |
183 |
URL res = EncodingUtil.class.getResource("/org/netbeans/modules/xml/core/resources/Bundle.properties"); |
184 |
MockUrlGrammarResult test = new MockUrlGrammarResult(); |
185 |
test.setContentURL(res); |
186 |
test.setExternal(false); |
187 |
|
188 |
CompletionDocumentation doc = createDocResourceResultSet(test); |
189 |
assertNull(doc.getURL()); |
190 |
assertTrue(doc.getText().contains("OpenIDE-Module-Name=XML Core")); |
191 |
|
192 |
// check that relative links still resolve to internal doc |
193 |
CompletionDocumentation internal = doc.resolveLink("mf-layer.xml"); |
194 |
assertNotNull("Relative links must be resolvable", internal); |
195 |
assertNull("Relative links cannot be opened in extbrowser", doc.getURL()); |
196 |
assertTrue("Content must be accessible", |
197 |
internal.getText().contains("org-netbeans-modules-xml-dtd-grammar-DTDGrammarQueryProvider.instance")); |
198 |
|
199 |
// check that absolute links resolve to external doc |
200 |
CompletionDocumentation external = doc.resolveLink("http://www.netbeans.org"); |
201 |
assertNotNull("Absolute links must be resolvable", external); |
202 |
assertEquals("Absolute links must have URL", external.getURL(), new URL("http://www.netbeans.org")); |
203 |
} |
204 |
|
205 |
/** |
206 |
* Checks that file-based documentation reverts to external as soon as possible |
207 |
* @throws Exception |
208 |
*/ |
209 |
public void testFileDocumentation() throws Exception { |
210 |
URL res = EncodingUtil.class.getResource("/org/netbeans/modules/xml/core/resources/Bundle.properties"); |
211 |
MockUrlGrammarResult test = new MockUrlGrammarResult(); |
212 |
test.setContentURL(res); |
213 |
test.setExternal(false); |
214 |
|
215 |
CompletionDocumentation doc = createDocResourceResultSet(test); |
216 |
assertNull(doc.getURL()); |
217 |
assertTrue("Invalid content", doc.getText().contains("OpenIDE-Module-Name=XML Core")); |
218 |
|
219 |
// check that resolve of file-based URL turns the doc to external: |
220 |
|
221 |
URL url = createResourceName("res/docResource.html"); |
222 |
CompletionDocumentation file = doc.resolveLink(url.toString()); |
223 |
assertNotNull(file); |
224 |
assertEquals("URL must be openable in browser", url, file.getURL()); |
225 |
assertTrue("Invalid content of the linked doc", file.getText().startsWith("This is an URL resource with <a href=")); |
226 |
} |
227 |
|
228 |
/** |
229 |
* Checks that relative and .. link resolution works OK. |
230 |
* |
231 |
* @throws Exception |
232 |
*/ |
233 |
public void testResolveRelativeLinks() throws Exception { |
234 |
CompletionDocumentation doc = createDocResourceResultSet(null); |
235 |
|
236 |
assertEquals(createResourceName("res/docResource.html"), doc.getURL()); |
237 |
|
238 |
CompletionDocumentation linked = doc.resolveLink("relativeLink1.html"); |
239 |
assertNotNull(linked); |
240 |
assertEquals("Relative link must be resolved", createResourceName("res/relativeLink1.html"), linked.getURL()); |
241 |
|
242 |
linked = doc.resolveLink("../parentDoc.html"); |
243 |
assertNotNull(linked); |
244 |
assertEquals("Link to resource in parent folder must be resolved", createResourceName("parentDoc.html"), linked.getURL()); |
245 |
} |
246 |
|
247 |
/** |
248 |
* Checks that DS returning 'external' provides URL and resolves links, although |
249 |
* no custom resolver is given |
250 |
* |
251 |
* @throws Exception |
252 |
*/ |
253 |
public void testNetworkUrlDocumentation() throws Exception { |
254 |
MockUrlGrammarResult test = new MockUrlGrammarResult(); |
255 |
test.setExternal(true); |
256 |
test.setContentURL(new URL("http://www.netbeans.org")); |
257 |
|
258 |
CompletionDocumentation doc = createDocResourceResultSet(test); |
259 |
assertEquals("External documentation must have URL", new URL("http://www.netbeans.org"), doc.getURL()); |
260 |
|
261 |
CompletionDocumentation resolved = doc.resolveLink("index.html"); |
262 |
assertEquals("Resolved external link must have URL", new URL("http://www.netbeans.org/index.html"), resolved.getURL()); |
263 |
} |
264 |
|
265 |
/** |
266 |
* Checks that without content URL, no item is produced |
267 |
* @throws Exception |
268 |
*/ |
269 |
public void testNoContentUrl() throws Exception { |
270 |
MockUrlGrammarResult res = new MockUrlGrammarResult(); |
271 |
CompletionDocumentation doc = createDocResourceResultSet(res); |
272 |
|
273 |
assertNull(doc); |
274 |
} |
275 |
|
276 |
public void testCustomResolveLink() throws Exception { |
277 |
MockUrlGrammarResult res = new MockUrlGrammarResult() { |
278 |
|
279 |
// resolves relative links in different directory |
280 |
@Override |
281 |
public DescriptionSource resolveLink(String link) { |
282 |
MockUrlGrammarResult res = new MockUrlGrammarResult(); |
283 |
URL base = createResourceName("res/" + link); |
284 |
res.setContentURL(base); |
285 |
res.setExternal(link.contains("Exist.html")); |
286 |
if (link.contains("customContent")) { |
287 |
res.setDescription(PLAIN_DESCRIPTION_TEXT); |
288 |
} |
289 |
return res; |
290 |
} |
291 |
}; |
292 |
res.setContentURL(createResourceName("res/docResource.html")); |
293 |
CompletionDocumentation doc = createDocResourceResultSet(res); |
294 |
|
295 |
// doc does not exist, but documentation item is there |
296 |
CompletionDocumentation notExisting = doc.resolveLink("doesNotExist.html"); |
297 |
assertNotNull(notExisting); |
298 |
// it is external, as defined by custom resolver |
299 |
assertEquals(createResourceName("doesNotExist.html"), notExisting.getURL()); |
300 |
// but contents cannot be fetched by the framework |
301 |
assertNull("Supplied description must take precedence", notExisting.getText()); |
302 |
|
303 |
// existing item |
304 |
CompletionDocumentation resolved = doc.resolveLink("relativeLink1.html"); |
305 |
// custom resolver says this is an internal link! |
306 |
assertNull("Must not be openable in browser", resolved.getURL()); |
307 |
// fwk is able to fetch contents |
308 |
assertTrue("Framework must fetch contents of linked URL", |
309 |
resolved.getText().startsWith("Resource referenced by relative link")); |
310 |
|
311 |
CompletionDocumentation parent = doc.resolveLink("customContent"); |
312 |
assertEquals(PLAIN_DESCRIPTION_TEXT, parent.getText()); |
313 |
} |
314 |
|
315 |
private static class MockUrlGrammarResult extends MockGrammarResult implements DescriptionSource { |
316 |
private URL contentURL; |
317 |
private boolean external; |
318 |
|
319 |
public void setContentURL(URL contentURL) { |
320 |
this.contentURL = contentURL; |
321 |
} |
322 |
|
323 |
public void setExternal(boolean external) { |
324 |
this.external = external; |
325 |
} |
326 |
|
327 |
@Override |
328 |
public URL getContentURL() { |
329 |
return contentURL; |
330 |
} |
331 |
|
332 |
@Override |
333 |
public boolean isExternal() { |
334 |
return external; |
335 |
} |
336 |
|
337 |
@Override |
338 |
public DescriptionSource resolveLink(String link) { |
339 |
return null; |
340 |
} |
341 |
|
342 |
} |
343 |
|
344 |
private static class MockGrammarResult extends AbstractNode implements GrammarResult { |
345 |
private String description; |
346 |
private String displayName; |
347 |
|
348 |
public void setDescription(String description) { |
349 |
this.description = description; |
350 |
} |
351 |
|
352 |
public void setDisplayName(String displayName) { |
353 |
this.displayName = displayName; |
354 |
} |
355 |
|
356 |
@Override |
357 |
public String getDescription() { |
358 |
return description; |
359 |
} |
360 |
|
361 |
@Override |
362 |
public String getDisplayName() { |
363 |
return displayName; |
364 |
} |
365 |
|
366 |
@Override |
367 |
public Icon getIcon(int kind) { |
368 |
return null; |
369 |
} |
370 |
|
371 |
@Override |
372 |
public boolean isEmptyElement() { |
373 |
return false; |
374 |
} |
375 |
|
376 |
@Override |
377 |
public short getNodeType() { |
378 |
return ELEMENT_NODE; |
379 |
} |
380 |
|
381 |
} |
382 |
} |