json: fix type=const in c++, add failure expectations for non-str const&enum
This commit is contained in:
parent
64799baea1
commit
5c50ffaeac
4 changed files with 58 additions and 6 deletions
|
@ -299,6 +299,10 @@ class SchemaConverter:
|
|||
self._refs_being_resolved.remove(ref)
|
||||
return ref_name
|
||||
|
||||
def _generate_constant_rule(self, value):
|
||||
assert isinstance(value, str), f'Only string constants are supported, got {value}'
|
||||
return self._format_literal(value)
|
||||
|
||||
def visit(self, schema, name):
|
||||
schema_type = schema.get('type')
|
||||
schema_format = schema.get('format')
|
||||
|
@ -314,10 +318,10 @@ class SchemaConverter:
|
|||
return self._add_rule(rule_name, self._generate_union_rule(name, [{'type': t} for t in schema_type]))
|
||||
|
||||
elif 'const' in schema:
|
||||
return self._add_rule(rule_name, self._format_literal(schema['const']))
|
||||
return self._add_rule(rule_name, self._generate_constant_rule(schema['const']))
|
||||
|
||||
elif 'enum' in schema:
|
||||
rule = ' | '.join((self._format_literal(v) for v in schema['enum']))
|
||||
rule = ' | '.join((self._generate_constant_rule(v) for v in schema['enum']))
|
||||
return self._add_rule(rule_name, rule)
|
||||
|
||||
elif schema_type in (None, 'object') and ('properties' in schema or 'additionalProperties' in schema):
|
||||
|
|
|
@ -547,6 +547,14 @@ public:
|
|||
visit_refs(schema);
|
||||
}
|
||||
|
||||
string _generate_constant_rule(const json& value) {
|
||||
if (!value.is_string()) {
|
||||
_errors.push_back("Only string constants are supported, got " + value.dump());
|
||||
return "";
|
||||
}
|
||||
return _format_literal(value.get<string>());
|
||||
}
|
||||
|
||||
string visit(const json& schema, const string& name) {
|
||||
json schema_type = schema.contains("type") ? schema["type"] : json();
|
||||
string schema_format = schema.contains("format") ? schema["format"].get<string>() : "";
|
||||
|
@ -564,11 +572,11 @@ public:
|
|||
}
|
||||
return _add_rule(rule_name, _generate_union_rule(name, schema_types));
|
||||
} else if (schema.contains("const")) {
|
||||
return _add_rule(rule_name, _format_literal(schema["const"].dump()));
|
||||
return _add_rule(rule_name, _generate_constant_rule(schema["const"]));
|
||||
} else if (schema.contains("enum")) {
|
||||
vector<string> enum_values;
|
||||
for (const auto& v : schema["enum"]) {
|
||||
enum_values.push_back(_format_literal(v.dump()));
|
||||
enum_values.push_back(_generate_constant_rule(v));
|
||||
}
|
||||
return _add_rule(rule_name, join(enum_values.begin(), enum_values.end(), " | "));
|
||||
} else if ((schema_type.is_null() || schema_type == "object")
|
||||
|
|
|
@ -325,6 +325,13 @@ export class SchemaConverter {
|
|||
return refName;
|
||||
}
|
||||
|
||||
_generateConstantRule(value) {
|
||||
if (typeof value !== 'string') {
|
||||
throw new Error('Only string constants are supported, got ' + JSON.stringify(value));
|
||||
}
|
||||
return this._formatLiteral(value);
|
||||
}
|
||||
|
||||
visit(schema, name) {
|
||||
const schemaType = schema.type;
|
||||
const schemaFormat = schema.format;
|
||||
|
@ -338,9 +345,12 @@ export class SchemaConverter {
|
|||
} else if (Array.isArray(schemaType)) {
|
||||
return this._addRule(ruleName, this._generateUnionRule(name, schemaType.map(t => ({ type: t }))));
|
||||
} else if ('const' in schema) {
|
||||
return this._addRule(ruleName, this._formatLiteral(schema.const));
|
||||
if (typeof schema.const !== 'string') {
|
||||
throw new Error('Only string constants are supported, got ' + JSON.stringify(schema.const));
|
||||
}
|
||||
return this._addRule(ruleName, this._generateConstantRule(schema.const));
|
||||
} else if ('enum' in schema) {
|
||||
const rule = schema.enum.map(v => this._formatLiteral(v)).join(' | ');
|
||||
const rule = schema.enum.map(v => this._generateConstantRule(v)).join(' | ');
|
||||
return this._addRule(ruleName, rule);
|
||||
} else if ((schemaType === undefined || schemaType === 'object') && ('properties' in schema || 'additionalProperties' in schema)) {
|
||||
const required = new Set(schema.required || []);
|
||||
|
|
|
@ -155,6 +155,36 @@ static void test_all(const string& lang, std::function<void(const TestCase&)> ru
|
|||
)"""
|
||||
});
|
||||
|
||||
test({
|
||||
SUCCESS,
|
||||
"string const",
|
||||
R"""({
|
||||
"const": "foo"
|
||||
})""",
|
||||
R"""(
|
||||
root ::= "\"foo\""
|
||||
space ::= " "?
|
||||
)"""
|
||||
});
|
||||
|
||||
test({
|
||||
FAILURE,
|
||||
"non-string const",
|
||||
R"""({
|
||||
"const": 123
|
||||
})""",
|
||||
""
|
||||
});
|
||||
|
||||
test({
|
||||
FAILURE,
|
||||
"non-string enum",
|
||||
R"""({
|
||||
"enum": [123]
|
||||
})""",
|
||||
""
|
||||
});
|
||||
|
||||
test({
|
||||
SUCCESS,
|
||||
"tuple1",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue