Skip to content

Commit

Permalink
WIP add unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed Sep 19, 2022
1 parent 71e3128 commit daf5a1b
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public enum RNGErrorCode implements IXMLErrorCode {
IncompleteContentModel,
BadTagName,
BadAttribute,
BadText,
MissingAttribute,
InvalidRelaxNG;

Expand Down Expand Up @@ -84,6 +85,9 @@ public static Range toLSPRange(XMLLocator location, RNGErrorCode code, String me
String attrName = m.group(1);
return XMLPositionUtility.selectAttributeNameFromGivenNameAt(attrName, offset, document);
}
case BadText: {
return XMLPositionUtility.selectContent(offset, document);
}
case InvalidRelaxNG: {
for (XMLModel xmlModel : document.getXMLModels()) {
if (message.contains(xmlModel.getHref())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
*/
public class RNGURIResolverExtension implements URIResolverExtension, IExternalGrammarLocationProvider {

private static final ResourceToDeploy RNG_RNG = new ResourceToDeploy("http://relaxng.org/relaxng.xsd",
private static final ResourceToDeploy RNG_XSD = new ResourceToDeploy("http://relaxng.org/relaxng.xsd",
"schemas/rng/relaxng.xsd");

// private static final String RELAXNG_NAMESPACE = "http://relaxng.org/ns/structure/1.0";

public RNGURIResolverExtension(IXMLDocumentProvider documentProvider) {

}
Expand Down Expand Up @@ -62,9 +64,8 @@ public String resolve(String baseLocation, String publicId, String systemId) {
private String resolve(String uri) {
if (DOMUtils.isRNG(uri)) {
try {
// XXX: I think this triggers the download, but confirm if this is needed
CacheResourcesManager.getResourceCachePath(RNG_RNG);
return RNG_RNG.getDeployedPath().toFile().toURI().toString();
CacheResourcesManager.getResourceCachePath(RNG_XSD);
return RNG_XSD.getDeployedPath().toFile().toURI().toString();
} catch (IOException e) {
// do nothing
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ public void setDocumentHandler(XMLDocumentHandler handler) {

@Override
public XMLDocumentHandler getDocumentHandler() {
return this; // TODO: ??
return this;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*******************************************************************************
* Copyright (c) 2022 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.extensions.contentmodel.validation;

import org.eclipse.lemminx.extensions.contentmodel.participants.RNGErrorCode;
import org.junit.jupiter.api.Test;
import static org.eclipse.lemminx.XMLAssert.d;
import static org.eclipse.lemminx.XMLAssert.testDiagnosticsFor;

/**
* Test validating XML files against RelaxNG schemas
*
* @author datho7561
*/
public class RelaxNGValidationTest {

@Test
public void relaxNGWithBrokenRNG() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/broken.rng\"?>\r\n" + //
"<root><item /></root>";
testDiagnosticsFor(xml, d(1, 17, 52, RNGErrorCode.InvalidRelaxNG));
}

@Test
public void relaxNGWithMissingAttributeValue() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/dressSize.rng\"?>\r\n" + //
"<dress size=\"\"></dress>";
testDiagnosticsFor(xml, d(2, 7, 11, RNGErrorCode.BadAttribute),
d(2, 23, 23, RNGErrorCode.IncompleteContentModel));
}

@Test
public void relaxNGWithBadAttributeValue() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/dressSize.rng\"?>\r\n" + //
"<dress size=\"sandwich\"></dress>";
testDiagnosticsFor(xml, d(2, 7, 11, RNGErrorCode.BadAttribute),
d(2, 31, 31, RNGErrorCode.IncompleteContentModel));
}

@Test
public void relaxNGWithUndefinedAttribute() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/dressSize.rng\"?>\r\n" + //
"<dress size=\"small\" asdf=\"\"></dress>";
testDiagnosticsFor(xml, d(2, 20, 24, RNGErrorCode.BadAttribute),
d(2, 36, 36, RNGErrorCode.IncompleteContentModel));
}

@Test
public void relaxNGWithUndefinedElement() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/dressSize.rng\"?>\r\n" + //
"<dress size=\"small\"><pant></pant></dress>";
testDiagnosticsFor(xml, d(2, 21,25, RNGErrorCode.BadTagName));
}

@Test
public void relaxNGWithInvalidElementContent() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/dressSize.rng\"?>\r\n" + //
"<dress size=\"small\">pant</dress>";
testDiagnosticsFor(xml, d(2, 20,24, RNGErrorCode.BadText));
}

@Test
public void relaxNGElementTextContentDoesntMatchType() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/dressSize.rng\"?>\r\n" + //
"<dress><size>pant</size></dress>";
// FIXME: only the innermost error should be reported
testDiagnosticsFor(xml, d(2, 13,17, RNGErrorCode.BadText),
d(2, 7, 24, RNGErrorCode.BadText));
}

@Test
public void relaxNGWithValidContent1() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/dressSize.rng\"?>\r\n" + //
"<dress size=\"medium\"></dress>";
testDiagnosticsFor(xml);
}

@Test
public void relaxNGWithValidContent2() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/dressSize.rng\"?>\r\n" + //
"<dress size=\"-42\"></dress>";
testDiagnosticsFor(xml);
}

@Test
public void relaxNGWithValidContent3() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/dressSize.rng\"?>\r\n" + //
"<dress><size>medium</size></dress>";
testDiagnosticsFor(xml);
}

@Test
public void relaxNGWithValidContent4() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \r\n" + //
"<?xml-model href=\"src/test/resources/rng/dressSize.rng\"?>\r\n" + //
"<dress><size>9000000</size></dress>";
testDiagnosticsFor(xml);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*******************************************************************************
* Copyright (c) 2022 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.extensions.rng;

import static org.eclipse.lemminx.XMLAssert.pd;
import static org.eclipse.lemminx.XMLAssert.r;

import org.eclipse.lemminx.AbstractCacheBasedTest;
import org.eclipse.lemminx.XMLAssert;
import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
import org.eclipse.lemminx.extensions.contentmodel.participants.XMLSchemaErrorCode;
import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationRootSettings;
import org.eclipse.lemminx.services.XMLLanguageService;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.junit.jupiter.api.Test;

/**
* Tests to make sure that *.rng associates with relaxng.xsd properly
*
* @author datho7561
*/
public class RNGUriResolverTest extends AbstractCacheBasedTest {

@Test
public void testValidatesRNGWithBadElement() throws Exception {

XMLValidationRootSettings validation = new XMLValidationRootSettings();
validation.setResolveExternalEntities(true);

XMLLanguageService ls = new XMLLanguageService();
ls.initializeIfNeeded();
// Disable download
ContentModelManager contentModelManager = ls.getComponent(ContentModelManager.class);
contentModelManager.setDownloadExternalResources(false);

String xsd = "<asdf xmlns=\"http://relaxng.org/ns/structure/1.0\"></asdf>";

String fileURI = "test.rng";
Diagnostic d = new Diagnostic(r(0, 1, 0, 5), "cvc-elt.1.a: Cannot find the declaration of element 'asdf'.",
DiagnosticSeverity.Error, "xml", XMLSchemaErrorCode.cvc_elt_1_a.getCode());

XMLAssert.testPublishDiagnosticsFor(xsd, fileURI, validation, ls, pd(fileURI, d));
}

@Test
public void testValidatesRNGWithMissingNamespace() throws Exception {

XMLValidationRootSettings validation = new XMLValidationRootSettings();
validation.setResolveExternalEntities(true);

XMLLanguageService ls = new XMLLanguageService();
ls.initializeIfNeeded();
// Disable download
ContentModelManager contentModelManager = ls.getComponent(ContentModelManager.class);
contentModelManager.setDownloadExternalResources(false);

String xsd = "<grammar></grammar>";

String fileURI = "test.rng";
Diagnostic d1 = new Diagnostic(r(0, 1, 0, 8),
"TargetNamespace.2: Expecting no namespace, but the schema document has a target namespace of 'http://relaxng.org/ns/structure/1.0'.",
DiagnosticSeverity.Error, "xml", XMLSchemaErrorCode.TargetNamespace_2.getCode());

Diagnostic d2 = new Diagnostic(r(0, 1, 0, 8), "cvc-elt.1.a: Cannot find the declaration of element 'grammar'.",
DiagnosticSeverity.Error, "xml", XMLSchemaErrorCode.cvc_elt_1_a.getCode());

XMLAssert.testPublishDiagnosticsFor(xsd, fileURI, validation, ls, pd(fileURI, d1, d2));
}

@Test
public void testValidatesRNGThatsValid() throws Exception {

XMLValidationRootSettings validation = new XMLValidationRootSettings();
validation.setResolveExternalEntities(true);

XMLLanguageService ls = new XMLLanguageService();
ls.initializeIfNeeded();
// Disable download
ContentModelManager contentModelManager = ls.getComponent(ContentModelManager.class);
contentModelManager.setDownloadExternalResources(false);

String xsd = "<grammar xmlns=\"http://relaxng.org/ns/structure/1.0\"></grammar>";

String fileURI = "test.rng";

XMLAssert.testPublishDiagnosticsFor(xsd, fileURI, validation, ls, pd(fileURI));
}

@Test
public void testValidatesRNGThatsValidWithNamespaceInPrefix() throws Exception {

XMLValidationRootSettings validation = new XMLValidationRootSettings();
validation.setResolveExternalEntities(true);

XMLLanguageService ls = new XMLLanguageService();
ls.initializeIfNeeded();
// Disable download
ContentModelManager contentModelManager = ls.getComponent(ContentModelManager.class);
contentModelManager.setDownloadExternalResources(false);

// FIXME: namespace is not handled correctly

// https://relaxng.org/tutorial-20011203.html
String xsd = "<rng:element name=\"addressBook\" xmlns:rng=\"http://relaxng.org/ns/structure/1.0\">\n" + //
"<rng:zeroOrMore>" + //
"<rng:element name=\"card\">\n" + //
"<rng:element name=\"name\">\n" + //
"<rng:text/>\n" + //
"</rng:element>\n" + //
"<rng:element name=\"email\">\n" + //
"<rng:text/>\n" + //
"</rng:element>\n" + //
"</rng:element>\n" + //
"</rng:zeroOrMore>\n" + //
"</rng:element>\n";

String fileURI = "test.rng";

XMLAssert.testPublishDiagnosticsFor(xsd, fileURI, validation, ls, pd(fileURI));
}

}
1 change: 1 addition & 0 deletions org.eclipse.lemminx/src/test/resources/rng/broken.rng
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<asdf xmlns="http://relaxng.org/ns/structure/1.0"></asdf>
27 changes: 27 additions & 0 deletions org.eclipse.lemminx/src/test/resources/rng/dressSize.rng
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<!-- approximation of
dresssize.xsd, the main difference being when you specify the size as an
integer, there are no bounds on the integer -->
<define name="dressSize">
<choice>
<value>small</value>
<value>medium</value>
<value>large</value>
<value>x-large</value>
<data type="integer" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" />
</choice>
</define>
<start>
<element name="dress">
<choice>
<element name="size">
<ref name="dressSize"></ref>
</element>
<attribute name="size">
<ref name="dressSize"></ref>
</attribute>
</choice>
</element>
</start>
</grammar>

0 comments on commit daf5a1b

Please sign in to comment.