@Test
    public void testObjectWithRequiredOptionalAndAdditionalProperties() {
        var schema = """
                {
                    "type": "object",
                    "properties": {
                        "and": {"type": "number"},
                        "also": {"type": "number"}
                    },
                    "required": ["and"],
                    "additionalProperties": {"type": "number"}
                }
                """;
        var expectedGrammar = """
                additional-k ::= ["] ( [a] ([l] ([s] ([o] char+ | [^"o] char*) | [^"s] char*) | [n] ([d] char+ | [^"d] char*) | [^"ln] char*) | [^"a] char* )? ["] space
                additional-kv ::= additional-k ":" space number
                also-kv ::= "\\"also\\"" space ":" space number
                also-rest ::= ( "," space additional-kv )*
                and-kv ::= "\\"and\\"" space ":" space number
                char ::= [^"\\\\\\x7F\\x00-\\x1F] | [\\\\] (["\\\\bfnrt] | "u" [0-9a-fA-F]{4})
                decimal-part ::= [0-9]{1,16}
                integral-part ::= [0] | [1-9] [0-9]{0,15}
                number ::= ("-"? integral-part) ("." decimal-part)? ([eE] [-+]? integral-part)? space
                root ::= "{" space and-kv ( "," space ( also-kv also-rest | additional-kv ( "," space additional-kv )* ) )? "}" space
                space ::= | " " | "\\n" [ \\t]{0,20}
                """;

        var actualGrammar = JsonSchemaToGrammar.convert(schema);
        assertEquals(expectedGrammar, actualGrammar);
    }
These tests are based on C++ unit tests from llama.cpp repository.
model-integration/src/test/java/ai/vespa/llm/clients/JsonSchemaToGrammarTest.java