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)
|
self._refs_being_resolved.remove(ref)
|
||||||
return ref_name
|
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):
|
def visit(self, schema, name):
|
||||||
schema_type = schema.get('type')
|
schema_type = schema.get('type')
|
||||||
schema_format = schema.get('format')
|
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]))
|
return self._add_rule(rule_name, self._generate_union_rule(name, [{'type': t} for t in schema_type]))
|
||||||
|
|
||||||
elif 'const' in schema:
|
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:
|
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)
|
return self._add_rule(rule_name, rule)
|
||||||
|
|
||||||
elif schema_type in (None, 'object') and ('properties' in schema or 'additionalProperties' in schema):
|
elif schema_type in (None, 'object') and ('properties' in schema or 'additionalProperties' in schema):
|
||||||
|
|
|
@ -547,6 +547,14 @@ public:
|
||||||
visit_refs(schema);
|
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) {
|
string visit(const json& schema, const string& name) {
|
||||||
json schema_type = schema.contains("type") ? schema["type"] : json();
|
json schema_type = schema.contains("type") ? schema["type"] : json();
|
||||||
string schema_format = schema.contains("format") ? schema["format"].get<string>() : "";
|
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));
|
return _add_rule(rule_name, _generate_union_rule(name, schema_types));
|
||||||
} else if (schema.contains("const")) {
|
} 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")) {
|
} else if (schema.contains("enum")) {
|
||||||
vector<string> enum_values;
|
vector<string> enum_values;
|
||||||
for (const auto& v : schema["enum"]) {
|
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(), " | "));
|
return _add_rule(rule_name, join(enum_values.begin(), enum_values.end(), " | "));
|
||||||
} else if ((schema_type.is_null() || schema_type == "object")
|
} else if ((schema_type.is_null() || schema_type == "object")
|
||||||
|
|
|
@ -325,6 +325,13 @@ export class SchemaConverter {
|
||||||
return refName;
|
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) {
|
visit(schema, name) {
|
||||||
const schemaType = schema.type;
|
const schemaType = schema.type;
|
||||||
const schemaFormat = schema.format;
|
const schemaFormat = schema.format;
|
||||||
|
@ -338,9 +345,12 @@ export class SchemaConverter {
|
||||||
} else if (Array.isArray(schemaType)) {
|
} else if (Array.isArray(schemaType)) {
|
||||||
return this._addRule(ruleName, this._generateUnionRule(name, schemaType.map(t => ({ type: t }))));
|
return this._addRule(ruleName, this._generateUnionRule(name, schemaType.map(t => ({ type: t }))));
|
||||||
} else if ('const' in schema) {
|
} 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) {
|
} 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);
|
return this._addRule(ruleName, rule);
|
||||||
} else if ((schemaType === undefined || schemaType === 'object') && ('properties' in schema || 'additionalProperties' in schema)) {
|
} else if ((schemaType === undefined || schemaType === 'object') && ('properties' in schema || 'additionalProperties' in schema)) {
|
||||||
const required = new Set(schema.required || []);
|
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({
|
test({
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
"tuple1",
|
"tuple1",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue