289 lines
11 KiB
Java
289 lines
11 KiB
Java
package p.packer.services;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.api.io.TempDir;
|
|
import p.packer.messages.assets.AssetFamilyCatalog;
|
|
import p.packer.messages.assets.OutputCodecCatalog;
|
|
import p.packer.messages.diagnostics.PackerDiagnosticCategory;
|
|
import p.packer.testing.PackerFixtureLocator;
|
|
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.util.Map;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
|
|
final class PackerAssetDeclarationParserTest {
|
|
private final PackerAssetDeclarationParser parser = new PackerAssetDeclarationParser(new ObjectMapper());
|
|
|
|
@TempDir
|
|
Path tempDir;
|
|
|
|
@Test
|
|
void parsesValidDeclarationFixture() {
|
|
final var result = parser.parse(PackerFixtureLocator.fixtureRoot("workspaces/managed-basic/assets/ui/atlas/asset.json"));
|
|
|
|
assertTrue(result.valid());
|
|
assertNotNull(result.declaration());
|
|
assertEquals(1, result.declaration().schemaVersion());
|
|
assertEquals("fixture-uuid-1", result.declaration().assetUuid());
|
|
assertEquals("ui_atlas", result.declaration().name());
|
|
assertEquals(AssetFamilyCatalog.GLYPH_BANK, result.declaration().assetFamily());
|
|
assertEquals("GLYPH/indexed_v1", result.declaration().outputFormat().displayName());
|
|
assertEquals(OutputCodecCatalog.NONE, result.declaration().outputCodec());
|
|
assertEquals(Map.of(), result.declaration().outputPipelineMetadata());
|
|
assertTrue(result.declaration().preloadEnabled());
|
|
}
|
|
|
|
@Test
|
|
void parsesPipelineMetadataAsDedicatedOutputObject() throws Exception {
|
|
final Path manifest = tempDir.resolve("asset.json");
|
|
Files.writeString(manifest, """
|
|
{
|
|
"schema_version": 1,
|
|
"asset_uuid": "uuid-pipeline",
|
|
"name": "pipeline_asset",
|
|
"type": "sound_bank",
|
|
"output": {
|
|
"format": "SOUND/v1",
|
|
"codec": "NONE",
|
|
"pipeline": {
|
|
"samples": {
|
|
"1": { "offset": 0, "length": 128 }
|
|
},
|
|
"normalized": true
|
|
}
|
|
},
|
|
"preload": { "enabled": true }
|
|
}
|
|
""");
|
|
|
|
final var result = parser.parse(manifest);
|
|
|
|
assertTrue(result.valid());
|
|
assertEquals(2, result.declaration().outputPipelineMetadata().size());
|
|
assertTrue(result.declaration().outputPipelineMetadata().get("normalized").asBoolean());
|
|
assertEquals(128, result.declaration().outputPipelineMetadata().get("samples").path("1").path("length").asInt());
|
|
}
|
|
|
|
@Test
|
|
void parsesSceneBankDeclaration() throws Exception {
|
|
final Path manifest = tempDir.resolve("scene-asset.json");
|
|
Files.writeString(manifest, """
|
|
{
|
|
"schema_version": 1,
|
|
"asset_uuid": "uuid-scene",
|
|
"name": "overworld_scene",
|
|
"type": "scene_bank",
|
|
"output": {
|
|
"format": "SCENE/tilemap_v1",
|
|
"codec": "NONE"
|
|
},
|
|
"preload": { "enabled": false }
|
|
}
|
|
""");
|
|
|
|
final var result = parser.parse(manifest);
|
|
|
|
assertTrue(result.valid());
|
|
assertEquals(AssetFamilyCatalog.SCENE_BANK, result.declaration().assetFamily());
|
|
assertEquals("SCENE/tilemap_v1", result.declaration().outputFormat().displayName());
|
|
assertEquals(OutputCodecCatalog.NONE, result.declaration().outputCodec());
|
|
}
|
|
|
|
@Test
|
|
void parsesLegacySceneBankDeclarationFormatAsTilemapContract() throws Exception {
|
|
final Path manifest = tempDir.resolve("legacy-scene-asset.json");
|
|
Files.writeString(manifest, """
|
|
{
|
|
"schema_version": 1,
|
|
"asset_uuid": "uuid-scene-legacy",
|
|
"name": "overworld_scene",
|
|
"type": "scene_bank",
|
|
"output": {
|
|
"format": "SCENE/tiled_v1",
|
|
"codec": "NONE"
|
|
},
|
|
"preload": { "enabled": false }
|
|
}
|
|
""");
|
|
|
|
final var result = parser.parse(manifest);
|
|
|
|
assertTrue(result.valid());
|
|
assertEquals(AssetFamilyCatalog.SCENE_BANK, result.declaration().assetFamily());
|
|
assertEquals("SCENE/tilemap_v1", result.declaration().outputFormat().displayName());
|
|
assertEquals(OutputCodecCatalog.NONE, result.declaration().outputCodec());
|
|
}
|
|
|
|
@Test
|
|
void rejectsNonObjectPipelineMetadata() throws Exception {
|
|
final Path manifest = tempDir.resolve("asset.json");
|
|
Files.writeString(manifest, """
|
|
{
|
|
"schema_version": 1,
|
|
"asset_uuid": "uuid-pipeline",
|
|
"name": "pipeline_asset",
|
|
"type": "glyph_bank",
|
|
"output": {
|
|
"format": "GLYPH/indexed_v1",
|
|
"codec": "NONE",
|
|
"pipeline": []
|
|
},
|
|
"preload": { "enabled": true }
|
|
}
|
|
""");
|
|
|
|
final var result = parser.parse(manifest);
|
|
|
|
assertFalse(result.valid());
|
|
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("output.pipeline")));
|
|
}
|
|
|
|
@Test
|
|
void parsesPaletteDeclarationsUsingExplicitIndexContract() throws Exception {
|
|
final Path manifest = tempDir.resolve("asset.json");
|
|
Files.writeString(manifest, """
|
|
{
|
|
"schema_version": 1,
|
|
"asset_uuid": "uuid-palette-contract",
|
|
"name": "palette_asset",
|
|
"type": "glyph_bank",
|
|
"output": {
|
|
"format": "GLYPH/indexed_v1",
|
|
"codec": "NONE",
|
|
"pipeline": {
|
|
"palettes": [
|
|
{
|
|
"index": 1,
|
|
"palette": {
|
|
"originalArgb8888": [4294901760],
|
|
"convertedRgb565": [63488]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"preload": { "enabled": true }
|
|
}
|
|
""");
|
|
|
|
final var result = parser.parse(manifest);
|
|
|
|
assertTrue(result.valid());
|
|
assertTrue(result.declaration().outputPipelineMetadata().get("palettes").isArray());
|
|
assertEquals(1, result.declaration().outputPipelineMetadata().get("palettes").get(0).path("index").asInt());
|
|
assertEquals(63488, result.declaration().outputPipelineMetadata().get("palettes").get(0).path("palette").path("convertedRgb565").get(0).asInt());
|
|
}
|
|
|
|
@Test
|
|
void rejectsPaletteDeclarationsWithDuplicateIndices() throws Exception {
|
|
final Path manifest = tempDir.resolve("asset.json");
|
|
Files.writeString(manifest, """
|
|
{
|
|
"schema_version": 1,
|
|
"asset_uuid": "uuid-palette-duplicate",
|
|
"name": "palette_asset",
|
|
"type": "glyph_bank",
|
|
"output": {
|
|
"format": "GLYPH/indexed_v1",
|
|
"codec": "NONE",
|
|
"pipeline": {
|
|
"palettes": [
|
|
{
|
|
"index": 0,
|
|
"palette": {
|
|
"originalArgb8888": [4294901760],
|
|
"convertedRgb565": [63488]
|
|
}
|
|
},
|
|
{
|
|
"index": 0,
|
|
"palette": {
|
|
"originalArgb8888": [4278255360],
|
|
"convertedRgb565": [2016]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"preload": { "enabled": true }
|
|
}
|
|
""");
|
|
|
|
final var result = parser.parse(manifest);
|
|
|
|
assertFalse(result.valid());
|
|
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("duplicate palette index 0")));
|
|
}
|
|
|
|
@Test
|
|
void rejectsMalformedJsonWithStructuralDiagnostic() {
|
|
final var result = parser.parse(PackerFixtureLocator.fixtureRoot("workspaces/invalid-malformed/assets/bad/asset.json"));
|
|
|
|
assertFalse(result.valid());
|
|
assertNull(result.declaration());
|
|
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.category() == PackerDiagnosticCategory.STRUCTURAL));
|
|
}
|
|
|
|
@Test
|
|
void rejectsMissingRequiredFields() {
|
|
final var result = parser.parse(PackerFixtureLocator.fixtureRoot("workspaces/invalid-missing-fields/assets/bad/asset.json"));
|
|
|
|
assertFalse(result.valid());
|
|
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("name")));
|
|
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("asset_uuid")));
|
|
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("format")));
|
|
}
|
|
|
|
@Test
|
|
void rejectsUnsupportedSchemaVersion() {
|
|
final var result = parser.parse(PackerFixtureLocator.fixtureRoot("workspaces/invalid-version/assets/bad/asset.json"));
|
|
|
|
assertFalse(result.valid());
|
|
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.category() == PackerDiagnosticCategory.VERSIONING));
|
|
}
|
|
|
|
@Test
|
|
void rejectsLegacyInputsField() throws Exception {
|
|
final Path manifest = tempDir.resolve("asset.json");
|
|
Files.writeString(manifest, """
|
|
{
|
|
"schema_version": 1,
|
|
"asset_uuid": "uuid-outside",
|
|
"name": "bad_asset",
|
|
"type": "glyph_bank",
|
|
"inputs": { "sprites": ["../outside.png"] },
|
|
"output": { "format": "GLYPH/indexed_v1", "codec": "NONE" },
|
|
"preload": { "enabled": true }
|
|
}
|
|
""");
|
|
|
|
final var result = parser.parse(manifest);
|
|
|
|
assertFalse(result.valid());
|
|
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("no longer supported")));
|
|
}
|
|
|
|
@Test
|
|
void rejectsUnknownAssetFamily() throws Exception {
|
|
final Path manifest = tempDir.resolve("asset.json");
|
|
Files.writeString(manifest, """
|
|
{
|
|
"schema_version": 1,
|
|
"asset_uuid": "uuid-video",
|
|
"name": "bad_asset",
|
|
"type": "video_bank",
|
|
"output": { "format": "GLYPH/indexed_v1", "codec": "NONE" },
|
|
"preload": { "enabled": true }
|
|
}
|
|
""");
|
|
|
|
final var result = parser.parse(manifest);
|
|
|
|
assertFalse(result.valid());
|
|
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("Field 'type' must be one of")));
|
|
}
|
|
}
|