diff --git a/specs/TilesetValidationSpec.ts b/specs/TilesetValidationSpec.ts index bbc926b2..a400bcf7 100644 --- a/specs/TilesetValidationSpec.ts +++ b/specs/TilesetValidationSpec.ts @@ -393,6 +393,14 @@ describe("Tileset validation", function () { expect(result.get(0).type).toEqual("REQUIRED_VALUE_NOT_FOUND"); }); + it("detects issues in tileChildrenEmptyArray", async function () { + const result = await Validators.validateTilesetFile( + "specs/data/tilesets/tileChildrenEmptyArray.json" + ); + expect(result.length).toEqual(1); + expect(result.get(0).type).toEqual("ARRAY_LENGTH_UNEXPECTED"); + }); + it("detects issues in tileContentBoundingVolumeInvalidType", async function () { const result = await Validators.validateTilesetFile( "specs/data/tilesets/tileContentBoundingVolumeInvalidType.json" diff --git a/specs/data/tilesets/tileChildrenEmptyArray.json b/specs/data/tilesets/tileChildrenEmptyArray.json new file mode 100644 index 00000000..6749322e --- /dev/null +++ b/specs/data/tilesets/tileChildrenEmptyArray.json @@ -0,0 +1,13 @@ +{ + "asset" : { + "version" : "1.1" + }, + "geometricError" : 2.0, + "root" : { + "boundingVolume" : { + "box" : [ 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ] + }, + "geometricError" : 1.0, + "children": [] + } +} \ No newline at end of file diff --git a/src/issues/JsonValidationIssues.ts b/src/issues/JsonValidationIssues.ts index 6c02788a..d5d9ffe6 100644 --- a/src/issues/JsonValidationIssues.ts +++ b/src/issues/JsonValidationIssues.ts @@ -158,6 +158,21 @@ export class JsonValidationIssues { return issue; } + /** + * A warning that indicates that an array SHOULD have had a + * certain length, but had a different length. + * + * @param path - The path for the `ValidationIssue` + * @param message - The message for the `ValidationIssue` + * @returns The `ValidationIssue` + */ + static ARRAY_LENGTH_UNEXPECTED(path: string, message: string) { + const type = "ARRAY_LENGTH_UNEXPECTED"; + const severity = ValidationIssueSeverity.WARNING; + const issue = new ValidationIssue(type, path, message, severity); + return issue; + } + /** * Indicates that the length of a string does not match the length * that is specified via the JSON schema, using the `minLength` diff --git a/src/validation/TileValidator.ts b/src/validation/TileValidator.ts index 80a0c458..93e916d4 100644 --- a/src/validation/TileValidator.ts +++ b/src/validation/TileValidator.ts @@ -347,19 +347,33 @@ export class TileValidator { const children = tile.children; const childrenPath = tilePath + "/children"; if (defined(children)) { - // The children MUST be an array of objects with at least 1 element + // The children MUST be an array of objects if ( !BasicValidator.validateArray( childrenPath, "children", children, - 1, + 0, undefined, "object", context ) ) { result = false; + } else { + // The children are an array of objects. + // The case that the array has a length of 0 will cause a warning, + // due to https://github.com/CesiumGS/3d-tiles/issues/752 + if (children.length === 0) { + const message = + `The 'children' array should contain at least 1 element, ` + + `but had a length of 0`; + const issue = JsonValidationIssues.ARRAY_LENGTH_UNEXPECTED( + childrenPath, + message + ); + context.addIssue(issue); + } } } return result;