planetiler/planetiler-custommap/src/test/java/com/onthegomap/planetiler/custommap/validator/SchemaValidatorTest.java

184 wiersze
5.6 KiB
Java

package com.onthegomap.planetiler.custommap.validator;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.onthegomap.planetiler.config.Arguments;
import com.onthegomap.planetiler.custommap.configschema.SchemaConfig;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
class SchemaValidatorTest {
@TempDir
Path tmpDir;
record Result(SchemaValidator.Result output, String cliOutput) {}
Result validate(String schema, String spec) throws IOException {
var args = Arguments.of();
var result = SchemaValidator.validate(
SchemaConfig.load(schema),
SchemaSpecification.load(spec),
args
);
for (var example : result.results()) {
if (example.issues().isFailure()) {
assertNotNull(example.issues().get());
}
}
// also exercise the cli writer and return what it would have printed to stdout
var cliOutput = validateCli(Files.writeString(tmpDir.resolve("schema"),
schema + "\nexamples: " + Files.writeString(tmpDir.resolve("spec.yml"), spec)), args);
// also test the case where the examples are embedded in the schema itself
assertEquals(
cliOutput,
validateCli(Files.writeString(tmpDir.resolve("schema"), schema + "\n" + spec), args)
);
// also test where examples points to a relative path (written in previous step)
assertEquals(
cliOutput,
validateCli(Files.writeString(tmpDir.resolve("schema"), schema + "\nexamples: spec.yml"), args)
);
return new Result(result, cliOutput);
}
private String validateCli(Path path, Arguments args) {
try (
var baos = new ByteArrayOutputStream();
var printStream = new PrintStream(baos, true, StandardCharsets.UTF_8)
) {
SchemaValidator.validateFromCli(
path,
args,
printStream
);
return baos.toString(StandardCharsets.UTF_8);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
String waterSchema = """
sources:
osm:
type: osm
url: geofabrik:rhode-island
layers:
- id: water
features:
- source: osm
geometry: polygon
include_when:
natural: water
attributes:
- key: natural
""";
private Result validateWater(String layer, String geometry, String tags, String allowExtraTags) throws IOException {
return validate(
waterSchema,
"""
examples:
- name: test output
input:
source: osm
geometry: polygon
tags:
natural: water
output:
layer: %s
geometry: %s
%s
tags:
%s
""".formatted(layer, geometry, allowExtraTags == null ? "" : allowExtraTags,
tags == null ? "" : tags.indent(6).strip())
);
}
@ParameterizedTest
@CsvSource(value = {
"true,water,polygon,natural: water,",
"true,water,polygon,,",
"true,water,polygon,'natural: water\nother: null',",
"false,water,polygon,natural: null,",
"false,water2,polygon,natural: water,",
"false,water,line,natural: water,",
"false,water,line,natural: water,",
"false,water,polygon,natural: water2,",
"false,water,polygon,'natural: water\nother: value',",
"true,water,polygon,natural: water,allow_extra_tags: true",
"true,water,polygon,natural: water,allow_extra_tags: false",
"true,water,polygon,,allow_extra_tags: true",
"false,water,polygon,,allow_extra_tags: false",
})
void testValidateWaterPolygon(boolean shouldBeOk, String layer, String geometry, String tags, String allowExtraTags)
throws IOException {
var results = validateWater(layer, geometry, tags, allowExtraTags);
assertEquals(1, results.output.results().size());
assertEquals("test output", results.output.results().get(0).example().name());
if (shouldBeOk) {
assertTrue(results.output.ok(), results.toString());
assertFalse(results.cliOutput.contains("FAIL"), "contained FAIL but should not have: " + results.cliOutput);
} else {
assertFalse(results.output.ok(), "Expected an issue, but there were none");
assertTrue(results.cliOutput.contains("FAIL"), "did not contain FAIL but should have: " + results.cliOutput);
}
}
@Test
void testValidationFailsWrongNumberOfFeatures() throws IOException {
var results = validate(
waterSchema,
"""
examples:
- name: test output
input:
source: osm
geometry: polygon
tags:
natural: water
output:
"""
);
assertFalse(results.output.ok(), results.toString());
results = validate(
waterSchema,
"""
examples:
- name: test output
input:
source: osm
geometry: polygon
tags:
natural: water
output:
- layer: water
geometry: polygon
tags:
natural: water
- layer: water2
geometry: polygon
tags:
natural: water2
"""
);
assertFalse(results.output.ok(), results.toString());
}
}