some more tests

This commit is contained in:
Andreas Penski (init) 2020-04-30 14:28:51 +02:00
parent fcf3ff2bf1
commit 16dc45ab46
11 changed files with 257 additions and 46 deletions

View file

@ -16,6 +16,8 @@ import javax.xml.validation.Schema;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import de.kosit.validationtool.api.Configuration;
@ -37,6 +39,7 @@ import net.sf.saxon.s9api.Processor;
* @author Andreas Penski
*/
@Slf4j
@Getter(AccessLevel.PACKAGE)
public class ConfigurationBuilder {
private final List<ScenarioBuilder> scenarios = new ArrayList<>();
@ -66,18 +69,33 @@ public class ConfigurationBuilder {
return this;
}
public ConfigurationBuilder date(final LocalDate localDate) {
this.date = localDate.toString();
return this;
}
public ConfigurationBuilder name(final String name) {
this.name = name;
return this;
}
/**
* Sets the date for this configuration.
*
* @param date the date
* @return this
*/
public ConfigurationBuilder date(final LocalDate date) {
if (date != null) {
this.date = date.toString();
}
return this;
}
/**
* Sets the date for this configuration.
*
* @param date the date
* @return this
*/
public ConfigurationBuilder date(final Date date) {
return date(LocalDate.ofEpochDay(date.getTime()));
return date(date != null ? LocalDate.ofEpochDay(date.getTime()) : null);
}
public ConfigurationBuilder with(final ScenarioBuilder scenarioBuilder) {

View file

@ -5,16 +5,19 @@ package de.kosit.validationtool.config;
*
* @author Andreas Penski
*/
public class Keys {
public final class Keys {
/**
* The actual scenarios file location as used with {@link ConfigurationLoader}.
*/
public static final String SCENARIOS_FILE = "scenarios_file";
/**
* The actual scenarios configuration represented as serializable tree. This either loaded from file or build manually
* via {@link ConfigurationBuilder}
*/
public static final String SCENARIO_DEFINITION = "scenario_definition";
private Keys() {
// hide
}
}

View file

@ -38,7 +38,7 @@ public class ReportBuilder implements Builder<Pair<CreateReportType, Transformat
@Override
public Result<Pair<CreateReportType, Transformation>, String> build(final ContentRepository repository) {
if (this.executable == null && this.source == null) {
return createError("Must supply source location and/or executable");
return createError(String.format("Must supply source location and/or executable for report '%s'", this.name));
}
final CreateReportType object = createObject();
Result<Pair<CreateReportType, Transformation>, String> result;

View file

@ -16,6 +16,7 @@ import org.apache.commons.lang3.tuple.Pair;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import de.kosit.validationtool.impl.ContentRepository;
import de.kosit.validationtool.impl.Scenario;
@ -37,6 +38,7 @@ import net.sf.saxon.s9api.XPathExecutable;
* @author Andreas Penski
*/
@RequiredArgsConstructor
@Slf4j
public class ScenarioBuilder implements Builder<Scenario> {
private static int nameCount = 0;
@ -45,9 +47,9 @@ public class ScenarioBuilder implements Builder<Scenario> {
private final Map<String, String> namespaces = new HashMap<>();
private final XPathBuilder matchConfig = new XPathBuilder();
private final XPathBuilder matchConfig = new XPathBuilder("match");
private final XPathBuilder acceptConfig = new XPathBuilder();
private final XPathBuilder acceptConfig = new XPathBuilder("accept");
@Getter(AccessLevel.PACKAGE)
private final String name;
@ -207,13 +209,17 @@ public class ScenarioBuilder implements Builder<Scenario> {
private void buildAccept(final ContentRepository repository, final List<String> errors, final Scenario scenario) {
this.acceptConfig.setNamespaces(this.namespaces);
final Result<XPathExecutable, String> result = this.acceptConfig.build(repository);
if (result.isValid()) {
scenario.setAcceptExecutable(result.getObject());
scenario.getConfiguration().setAcceptMatch(this.acceptConfig.getXPath());
this.namespaces.putAll(this.acceptConfig.getNamespaces());
if (this.acceptConfig.isAvailable()) {
final Result<XPathExecutable, String> result = this.acceptConfig.build(repository);
if (result.isValid()) {
scenario.setAcceptExecutable(result.getObject());
scenario.getConfiguration().setAcceptMatch(this.acceptConfig.getXPath());
this.namespaces.putAll(this.acceptConfig.getNamespaces());
} else {
errors.addAll(result.getErrors());
}
} else {
errors.addAll(result.getErrors());
log.debug("No accept configuration available");
}
}

View file

@ -37,7 +37,7 @@ public class SchemaBuilder implements Builder<Pair<ValidateWithXmlSchema, Schema
@Override
public Result<Pair<ValidateWithXmlSchema, Schema>, String> build(final ContentRepository repository) {
if (this.schema == null && this.schemaLocation == null) {
return createError("Must supply schema location and/or schema");
return createError(String.format("Must supply source location and/or executable for schema '%s'", this.name));
}
Result<Pair<ValidateWithXmlSchema, Schema>, String> result;
try {

View file

@ -38,7 +38,7 @@ public class SchematronBuilder implements Builder<Pair<ValidateWithSchematron, T
@Override
public Result<Pair<ValidateWithSchematron, Transformation>, String> build(final ContentRepository repository) {
if (this.executable == null && this.source == null) {
return createError("Must supply source location and/or executable");
return createError(String.format("Must supply source location and/or executable for schematron '%s'", this.name));
}
final ValidateWithSchematron object = createObject();
Result<Pair<ValidateWithSchematron, Transformation>, String> result;

View file

@ -1,5 +1,7 @@
package de.kosit.validationtool.config;
import static org.apache.commons.lang3.ObjectUtils.isNotEmpty;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@ -11,7 +13,9 @@ import org.apache.commons.lang3.ArrayUtils;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import de.kosit.validationtool.impl.ContentRepository;
import de.kosit.validationtool.impl.model.Result;
@ -23,11 +27,15 @@ import net.sf.saxon.s9api.XPathExecutable;
*
* @author Andreas Penski
*/
@RequiredArgsConstructor
@Data
@Slf4j
class XPathBuilder implements Builder<XPathExecutable> {
private static final String[] IGNORED_PREFIXES = new String[] { "xsd" };
private final String name;
private String xpath;
private XPathExecutable executable;
@ -44,19 +52,30 @@ class XPathBuilder implements Builder<XPathExecutable> {
public String getXPath() {
return this.xpath == null && this.executable != null ? this.executable.getUnderlyingExpression().getInternalExpression().toString()
: this.xpath;
}
public boolean isAvailable() {
return this.executable != null || isNotEmpty(this.xpath);
}
@Override
public Result<XPathExecutable, String> build(final ContentRepository repository) {
if (this.executable == null && this.xpath == null) {
return createError("No configuration for xpath expression found");
if (!isAvailable()) {
return createError(String.format("No configuration for %s xpath expression found", this.name));
}
if (this.executable == null) {
this.executable = repository.createXPath(this.xpath, this.namespaces);
} else {
this.xpath = extractExpression();
this.namespaces = extractNamespaces();
try {
if (this.executable == null) {
this.executable = repository.createXPath(this.xpath, this.namespaces);
} else {
this.xpath = extractExpression();
this.namespaces = extractNamespaces();
}
} catch (final IllegalStateException e) {
final String msg = String.format("Error creating %s xpath", this.name, e);
log.error(msg, e);
return new Result<>(Collections.singletonList(msg));
}
return new Result<>(this.executable);
}

View file

@ -3,23 +3,25 @@ package de.kosit.validationtool.impl;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import lombok.SneakyThrows;
/**
* @author Andreas Penski
*/
public class DateFactory {
private DateFactory() {
// hide
}
@SneakyThrows
public static XMLGregorianCalendar createTimestamp() {
try {
final GregorianCalendar cal = new GregorianCalendar();
cal.setTime(new Date());
return DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
} catch (final DatatypeConfigurationException e) {
throw new IllegalStateException("Can not create timestamp", e);
}
}
}

View file

@ -0,0 +1,88 @@
package de.kosit.validationtool.config;
import static de.kosit.validationtool.config.ConfigurationBuilder.report;
import static de.kosit.validationtool.config.ConfigurationBuilder.schematron;
import static de.kosit.validationtool.config.SimpleConfigTest.createSimpleConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
import java.net.URI;
import java.time.LocalDate;
import java.util.Date;
import org.hamcrest.Matchers;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
/**
* Test {@link ConfigurationBuilder}.
*
* @author Andreas Penski
*/
public class ConfigurationBuilderTest {
public static final LocalDate EPOCH = LocalDate.of(1970, 1, 1);
@Rule
public ExpectedException exceptions = ExpectedException.none();
@Test
public void testNoConfiguration() {
this.exceptions.expect(IllegalStateException.class);
new ConfigurationBuilder().build();
}
@Test
public void testNoFallback() {
this.exceptions.expect(IllegalStateException.class);
this.exceptions.expectMessage(Matchers.containsString("fallback"));
final ConfigurationBuilder builder = createSimpleConfiguration();
builder.with((FallbackBuilder) null);
builder.build();
}
@Test
public void testNoSchema() {
this.exceptions.expect(IllegalStateException.class);
this.exceptions.expectMessage(Matchers.containsString("schema"));
final ConfigurationBuilder builder = createSimpleConfiguration();
builder.getScenarios().get(0).validate((SchemaBuilder) null);
builder.build();
}
@Test
public void testInvalidSchematron() {
this.exceptions.expect(IllegalStateException.class);
this.exceptions.expectMessage(Matchers.containsString("schematron"));
final ConfigurationBuilder builder = createSimpleConfiguration();
builder.getScenarios().get(0).validate(schematron("invalid").source(URI.create("DoesNotExist")));
builder.build();
}
@Test
public void testInsufficientSchematron() {
this.exceptions.expect(IllegalStateException.class);
this.exceptions.expectMessage(Matchers.containsString("schematron"));
final ConfigurationBuilder builder = createSimpleConfiguration();
builder.getScenarios().get(0).validate(schematron("invalid"));
builder.build();
}
@Test
public void testNoReport() {
this.exceptions.expect(IllegalStateException.class);
this.exceptions.expectMessage(Matchers.containsString("report"));
final ConfigurationBuilder builder = createSimpleConfiguration();
builder.getScenarios().get(0).with(report("invalid"));
builder.build();
}
@Test
public void testDate() {
assertThat(createSimpleConfiguration().date(EPOCH).build().getDate()).isEqualTo("1970-01-01");
assertThat(createSimpleConfiguration().date(new Date(EPOCH.toEpochDay())).build().getDate()).isEqualTo("1970-01-01");
assertThat(createSimpleConfiguration().date((Date) null).build().getDate()).isEqualTo(LocalDate.now().toString());
assertThat(createSimpleConfiguration().date((LocalDate) null).build().getDate()).isEqualTo(LocalDate.now().toString());
}
}

View file

@ -0,0 +1,74 @@
package de.kosit.validationtool.config;
import static de.kosit.validationtool.config.SimpleConfigTest.createScenarioConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import de.kosit.validationtool.impl.Helper.Simple;
import de.kosit.validationtool.impl.Scenario;
import de.kosit.validationtool.impl.model.Result;
/**
* Test {@link ScenarioBuilder}.
*
* @author Andreas Penski
*/
public class ScenarioBuilderTest {
@Rule
public ExpectedException exceptions = ExpectedException.none();
@Test
public void simpleValid() {
final Result<Scenario, String> result = createScenarioConfiguration().build(Simple.createContentRepository());
assertThat(result.isValid()).isTrue();
assertThat(result.getObject().getConfiguration()).isNotNull();
}
@Test
public void testNoSchema() {
final ScenarioBuilder builder = createScenarioConfiguration();
builder.validate((SchemaBuilder) null);
final Result<Scenario, String> result = builder.build(Simple.createContentRepository());
assertThat(result.isValid()).isFalse();
assertThat(result.getErrors()).anyMatch(e -> e.contains("schema"));
}
@Test
public void testNoMatch() {
final ScenarioBuilder builder = createScenarioConfiguration();
builder.match((String) null);
final Result<Scenario, String> result = builder.build(Simple.createContentRepository());
assertThat(result.isValid()).isFalse();
assertThat(result.getErrors()).anyMatch(e -> e.contains("match"));
}
@Test
public void testInvalidMatch() {
final ScenarioBuilder builder = createScenarioConfiguration();
builder.match("/////");
final Result<Scenario, String> result = builder.build(Simple.createContentRepository());
assertThat(result.isValid()).isFalse();
assertThat(result.getErrors()).anyMatch(e -> e.contains("match"));
}
@Test
public void testNoAccept() {
final ScenarioBuilder builder = createScenarioConfiguration();
builder.acceptWith((String) null);
final Result<Scenario, String> result = builder.build(Simple.createContentRepository());
assertThat(result.isValid()).isTrue();
}
@Test
public void testInvalidAccept() {
final ScenarioBuilder builder = createScenarioConfiguration();
builder.acceptWith("/////");
final Result<Scenario, String> result = builder.build(Simple.createContentRepository());
assertThat(result.isValid()).isFalse();
assertThat(result.getErrors()).anyMatch(e -> e.contains("accept"));
}
}

View file

@ -25,25 +25,26 @@ public class SimpleConfigTest {
@Test
public void testSimpleWithApi() {
//@formatter:off
final Configuration config =
Configuration.create().name("Simple-API")
.with(scenario("simple")
.validate(schema("Sample Schema").schemaLocation(URI.create("simple.xsd")))
.with(report("Report für eRechnung").source("report.xsl"))
.acceptWith("count(//test:rejected) = 0")
.declareNamespace("cri", "http://www.xoev.de/de/validator/framework/1/createreportinput")
.declareNamespace("rpt", "http://validator.kosit.de/test-report")
.declareNamespace("test", "http://validator.kosit.de/test-sample")
.match("/test:simple")
// .description("awesome api")
)
.with(fallback().name("default").source("report.xsl"))
.resolvingMode(ResolvingMode.STRICT_RELATIVE)
.useRepository(Simple.REPOSITORY_URI).build();
final Configuration config = createSimpleConfiguration().build();
//@formatter:on
final DefaultCheck check = new DefaultCheck(config);
final Result result = check.checkInput(InputFactory.read(Simple.SIMPLE_VALID));
assertThat(result).isNotNull();
}
static ConfigurationBuilder createSimpleConfiguration() {
return Configuration.create().name("Simple-API").with(createScenarioConfiguration()
// .description("awesome api")
).with(fallback().name("default").source("report.xsl"))
.resolvingMode(ResolvingMode.STRICT_RELATIVE).useRepository(Simple.REPOSITORY_URI);
}
static ScenarioBuilder createScenarioConfiguration() {
return scenario("simple").validate(schema("Sample Schema").schemaLocation(URI.create("simple.xsd")))
.with(report("Report für eRechnung").source("report.xsl")).acceptWith("count(//test:rejected) = 0")
.declareNamespace("cri", "http://www.xoev.de/de/validator/framework/1/createreportinput")
.declareNamespace("rpt", "http://validator.kosit.de/test-report")
.declareNamespace("test", "http://validator.kosit.de/test-sample").match("/test:simple");
}
}