@@ -217,10 +217,18 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
qapi-schema-test.json quoted-structural-chars.json \
trailing-comma-list.json trailing-comma-object.json \
unclosed-list.json unclosed-object.json unclosed-string.json \
- duplicate-key.json union-invalid-base.json flat-union-no-base.json \
- flat-union-invalid-discriminator.json \
+ duplicate-key.json union-invalid-base.json union-bad-branch.json \
+ union-optional-branch.json union-unknown.json union-max.json \
+ flat-union-optional-discriminator.json flat-union-no-base.json \
+ flat-union-invalid-discriminator.json flat-union-inline.json \
flat-union-invalid-branch-key.json flat-union-reverse-define.json \
- flat-union-string-discriminator.json \
+ flat-union-string-discriminator.json union-base-no-discriminator.json \
+ flat-union-bad-discriminator.json flat-union-bad-base.json \
+ flat-union-base-star.json flat-union-int-branch.json \
+ flat-union-base-union.json flat-union-branch-clash.json \
+ alternate-nested.json alternate-unknown.json alternate-clash.json \
+ alternate-good.json alternate-base.json alternate-array.json \
+ alternate-conflict-string.json alternate-conflict-dict.json \
include-simple.json include-relpath.json include-format-err.json \
include-non-file.json include-no-file.json include-before-err.json \
include-nested-err.json include-self-cycle.json include-cycle.json \
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,8 @@
+# FIXME: we do not support array branches of anonymous unions yet
+# TODO: should we support this?
+{ 'type': 'One',
+ 'data': { 'name': 'str' } }
+{ 'union': 'MyUnion',
+ 'discriminator': {},
+ 'data': { 'one': 'One',
+ 'two': [ 'int' ] } }
new file mode 100644
@@ -0,0 +1,4 @@
+[OrderedDict([('type', 'One'), ('data', OrderedDict([('name', 'str')]))]),
+ OrderedDict([('union', 'MyUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('one', 'One'), ('two', ['int'])]))])]
+[{'enum_name': 'MyUnionKind', 'enum_values': None}]
+[OrderedDict([('type', 'One'), ('data', OrderedDict([('name', 'str')]))])]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,7 @@
+# FIXME: we should reject anonymous union with base type
+{ 'type': 'Base',
+ 'data': { 'string': 'str' } }
+{ 'union': 'MyUnion',
+ 'base': 'Base',
+ 'discriminator': {},
+ 'data': { 'number': 'int' } }
new file mode 100644
@@ -0,0 +1,4 @@
+[OrderedDict([('type', 'Base'), ('data', OrderedDict([('string', 'str')]))]),
+ OrderedDict([('union', 'MyUnion'), ('base', 'Base'), ('discriminator', OrderedDict()), ('data', OrderedDict([('number', 'int')]))])]
+[{'enum_name': 'MyUnionKind', 'enum_values': None}]
+[OrderedDict([('type', 'Base'), ('data', OrderedDict([('string', 'str')]))])]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,4 @@
+# FIXME: we should detect C enum collisions in an anonymous union
+{ 'union': 'Union1',
+ 'discriminator': {},
+ 'data': { 'one': 'str', 'ONE': 'int' } }
new file mode 100644
@@ -0,0 +1,3 @@
+[OrderedDict([('union', 'Union1'), ('discriminator', OrderedDict()), ('data', OrderedDict([('one', 'str'), ('ONE', 'int')]))])]
+[{'enum_name': 'Union1Kind', 'enum_values': None}]
+[]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,9 @@
+# FIXME: we should reject anonymous unions with multiple object branches
+{ 'type': 'One',
+ 'data': { 'name': 'str' } }
+{ 'type': 'Two',
+ 'data': { 'value': 'int' } }
+{ 'union': 'MyUnion',
+ 'discriminator': {},
+ 'data': { 'one': 'One',
+ 'two': 'Two' } }
new file mode 100644
@@ -0,0 +1,6 @@
+[OrderedDict([('type', 'One'), ('data', OrderedDict([('name', 'str')]))]),
+ OrderedDict([('type', 'Two'), ('data', OrderedDict([('value', 'int')]))]),
+ OrderedDict([('union', 'MyUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('one', 'One'), ('two', 'Two')]))])]
+[{'enum_name': 'MyUnionKind', 'enum_values': None}]
+[OrderedDict([('type', 'One'), ('data', OrderedDict([('name', 'str')]))]),
+ OrderedDict([('type', 'Two'), ('data', OrderedDict([('value', 'int')]))])]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,7 @@
+# FIXME: we should reject anonymous unions with multiple string-like branches
+{ 'enum': 'Enum',
+ 'data': [ 'hello', 'world' ] }
+{ 'union': 'MyUnion',
+ 'discriminator': {},
+ 'data': { 'one': 'str',
+ 'two': 'Enum' } }
new file mode 100644
@@ -0,0 +1,5 @@
+[OrderedDict([('enum', 'Enum'), ('data', ['hello', 'world'])]),
+ OrderedDict([('union', 'MyUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('one', 'str'), ('two', 'Enum')]))])]
+[{'enum_name': 'Enum', 'enum_values': ['hello', 'world']},
+ {'enum_name': 'MyUnionKind', 'enum_values': None}]
+[]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,10 @@
+# Working example of anonymous union
+{ 'type': 'Data',
+ 'data': { '*number': 'int', '*name': 'str' } }
+{ 'enum': 'Enum',
+ 'data': [ 'hello', 'world' ] }
+{ 'union': 'MyUnion',
+ 'discriminator': {},
+ 'data': { 'value': 'int',
+ 'string': 'Enum',
+ 'struct': 'Data' } }
new file mode 100644
@@ -0,0 +1,6 @@
+[OrderedDict([('type', 'Data'), ('data', OrderedDict([('*number', 'int'), ('*name', 'str')]))]),
+ OrderedDict([('enum', 'Enum'), ('data', ['hello', 'world'])]),
+ OrderedDict([('union', 'MyUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('value', 'int'), ('string', 'Enum'), ('struct', 'Data')]))])]
+[{'enum_name': 'Enum', 'enum_values': ['hello', 'world']},
+ {'enum_name': 'MyUnionKind', 'enum_values': None}]
+[OrderedDict([('type', 'Data'), ('data', OrderedDict([('*number', 'int'), ('*name', 'str')]))])]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,7 @@
+# FIXME: we should reject a nested anonymous union branch
+{ 'union': 'Union1',
+ 'discriminator': {},
+ 'data': { 'name': 'str', 'value': 'int' } }
+{ 'union': 'Union2',
+ 'discriminator': {},
+ 'data': { 'nested': 'Union1' } }
new file mode 100644
@@ -0,0 +1,5 @@
+[OrderedDict([('union', 'Union1'), ('discriminator', OrderedDict()), ('data', OrderedDict([('name', 'str'), ('value', 'int')]))]),
+ OrderedDict([('union', 'Union2'), ('discriminator', OrderedDict()), ('data', OrderedDict([('nested', 'Union1')]))])]
+[{'enum_name': 'Union1Kind', 'enum_values': None},
+ {'enum_name': 'Union2Kind', 'enum_values': None}]
+[]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,4 @@
+# FIXME: we should reject an anonymous union with unknown type in branch
+{ 'union': 'Union',
+ 'discriminator': {},
+ 'data': { 'unknown': 'MissingType' } }
new file mode 100644
@@ -0,0 +1,3 @@
+[OrderedDict([('union', 'Union'), ('discriminator', OrderedDict()), ('data', OrderedDict([('unknown', 'MissingType')]))])]
+[{'enum_name': 'UnionKind', 'enum_values': None}]
+[]
new file mode 100644
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-bad-base.json:9: Base 'OrderedDict([('enum1', 'TestEnum'), ('kind', 'str')])' is not a valid type
new file mode 100644
@@ -0,0 +1 @@
+1
new file mode 100644
@@ -0,0 +1,13 @@
+# FIXME: poor message: we require the base to be an existing complex type
+# TODO: should we allow an anonymous inline base type?
+{ 'enum': 'TestEnum',
+ 'data': [ 'value1', 'value2' ] }
+{ 'type': 'TestTypeA',
+ 'data': { 'string': 'str' } }
+{ 'type': 'TestTypeB',
+ 'data': { 'integer': 'int' } }
+{ 'union': 'TestUnion',
+ 'base': { 'enum1': 'TestEnum', 'kind': 'str' },
+ 'discriminator': 'enum1',
+ 'data': { 'value1': 'TestTypeA',
+ 'value2': 'TestTypeB' } }
new file mode 100644
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,14 @@
+# FIXME: we should require the discriminator to be a string naming a base-type member
+{ 'enum': 'TestEnum',
+ 'data': [ 'value1', 'value2' ] }
+{ 'type': 'TestBase',
+ 'data': { 'enum1': 'TestEnum', 'kind': 'str' } }
+{ 'type': 'TestTypeA',
+ 'data': { 'string': 'str' } }
+{ 'type': 'TestTypeB',
+ 'data': { 'integer': 'int' } }
+{ 'union': 'TestUnion',
+ 'base': 'TestBase',
+ 'discriminator': [],
+ 'data': { 'kind1': 'TestTypeA',
+ 'kind2': 'TestTypeB' } }
new file mode 100644
@@ -0,0 +1,10 @@
+[OrderedDict([('enum', 'TestEnum'), ('data', ['value1', 'value2'])]),
+ OrderedDict([('type', 'TestBase'), ('data', OrderedDict([('enum1', 'TestEnum'), ('kind', 'str')]))]),
+ OrderedDict([('type', 'TestTypeA'), ('data', OrderedDict([('string', 'str')]))]),
+ OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('union', 'TestUnion'), ('base', 'TestBase'), ('discriminator', []), ('data', OrderedDict([('kind1', 'TestTypeA'), ('kind2', 'TestTypeB')]))])]
+[{'enum_name': 'TestEnum', 'enum_values': ['value1', 'value2']},
+ {'enum_name': 'TestUnionKind', 'enum_values': None}]
+[OrderedDict([('type', 'TestBase'), ('data', OrderedDict([('enum1', 'TestEnum'), ('kind', 'str')]))]),
+ OrderedDict([('type', 'TestTypeA'), ('data', OrderedDict([('string', 'str')]))]),
+ OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))])]
new file mode 100644
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-base-star.json:8: Base '**' is not a valid type
new file mode 100644
@@ -0,0 +1 @@
+1
new file mode 100644
@@ -0,0 +1,12 @@
+# we require the base to be an existing complex type
+{ 'enum': 'TestEnum',
+ 'data': [ 'value1', 'value2' ] }
+{ 'type': 'TestTypeA',
+ 'data': { 'string': 'str' } }
+{ 'type': 'TestTypeB',
+ 'data': { 'integer': 'int' } }
+{ 'union': 'TestUnion',
+ 'base': '**',
+ 'discriminator': 'enum1',
+ 'data': { 'value1': 'TestTypeA',
+ 'value2': 'TestTypeB' } }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-base-union.json:11: Base 'UnionBase' is not a valid type
new file mode 100644
@@ -0,0 +1 @@
+1
new file mode 100644
@@ -0,0 +1,15 @@
+# FIXME: the error message needs help: we require the base to be a struct
+{ 'enum': 'TestEnum',
+ 'data': [ 'value1', 'value2' ] }
+{ 'type': 'TestTypeA',
+ 'data': { 'string': 'str' } }
+{ 'type': 'TestTypeB',
+ 'data': { 'integer': 'int' } }
+{ 'union': 'UnionBase',
+ 'data': { 'kind1': 'TestTypeA',
+ 'kind2': 'TestTypeB' } }
+{ 'union': 'TestUnion',
+ 'base': 'UnionBase',
+ 'discriminator': 'type',
+ 'data': { 'kind1': 'TestTypeA',
+ 'kind2': 'TestTypeB' } }
new file mode 100644
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,14 @@
+# FIXME: we should check for no duplicate keys between branches and base
+{ 'enum': 'TestEnum',
+ 'data': [ 'value1', 'value2' ] }
+{ 'type': 'Base',
+ 'data': { 'enum1': 'TestEnum', 'name': 'str' } }
+{ 'type': 'Branch1',
+ 'data': { 'name': 'str' } }
+{ 'type': 'Branch2',
+ 'data': { 'value': 'int' } }
+{ 'union': 'TestUnion',
+ 'base': 'Base',
+ 'discriminator': 'enum1',
+ 'data': { 'value1': 'Branch1',
+ 'value2': 'Branch2' } }
new file mode 100644
@@ -0,0 +1,9 @@
+[OrderedDict([('enum', 'TestEnum'), ('data', ['value1', 'value2'])]),
+ OrderedDict([('type', 'Base'), ('data', OrderedDict([('enum1', 'TestEnum'), ('name', 'str')]))]),
+ OrderedDict([('type', 'Branch1'), ('data', OrderedDict([('name', 'str')]))]),
+ OrderedDict([('type', 'Branch2'), ('data', OrderedDict([('value', 'int')]))]),
+ OrderedDict([('union', 'TestUnion'), ('base', 'Base'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'Branch1'), ('value2', 'Branch2')]))])]
+[{'enum_name': 'TestEnum', 'enum_values': ['value1', 'value2']}]
+[OrderedDict([('type', 'Base'), ('data', OrderedDict([('enum1', 'TestEnum'), ('name', 'str')]))]),
+ OrderedDict([('type', 'Branch1'), ('data', OrderedDict([('name', 'str')]))]),
+ OrderedDict([('type', 'Branch2'), ('data', OrderedDict([('value', 'int')]))])]
new file mode 100644
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-inline.json:7: Base 'OrderedDict([('enum1', 'TestEnum'), ('kind', 'str')])' is not a valid type
new file mode 100644
@@ -0,0 +1 @@
+1
new file mode 100644
@@ -0,0 +1,11 @@
+# FIXME: poor message: we require branches to be a complex type name
+# TODO: should we allow anonymous inline types?
+{ 'enum': 'TestEnum',
+ 'data': [ 'value1', 'value2' ] }
+{ 'type': 'Base',
+ 'data': { 'enum1': 'TestEnum', 'kind': 'str' } }
+{ 'union': 'TestUnion',
+ 'base': { 'enum1': 'TestEnum', 'kind': 'str' },
+ 'discriminator': 'enum1',
+ 'data': { 'value1': { 'string': 'str' },
+ 'value2': { 'integer': 'int' } } }
new file mode 100644
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,12 @@
+# FIXME: we should require flat union branches to be a complex type
+{ 'enum': 'TestEnum',
+ 'data': [ 'value1', 'value2' ] }
+{ 'type': 'Base',
+ 'data': { 'enum1': 'TestEnum' } }
+{ 'type': 'TestTypeB',
+ 'data': { 'integer': 'int' } }
+{ 'union': 'TestUnion',
+ 'base': 'Base',
+ 'discriminator': 'enum1',
+ 'data': { 'value1': 'int',
+ 'value2': 'TestTypeB' } }
new file mode 100644
@@ -0,0 +1,7 @@
+[OrderedDict([('enum', 'TestEnum'), ('data', ['value1', 'value2'])]),
+ OrderedDict([('type', 'Base'), ('data', OrderedDict([('enum1', 'TestEnum')]))]),
+ OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('union', 'TestUnion'), ('base', 'Base'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'int'), ('value2', 'TestTypeB')]))])]
+[{'enum_name': 'TestEnum', 'enum_values': ['value1', 'value2']}]
+[OrderedDict([('type', 'Base'), ('data', OrderedDict([('enum1', 'TestEnum')]))]),
+ OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))])]
@@ -1 +1 @@
-tests/qapi-schema/flat-union-no-base.json:7: Flat union 'TestUnion' must have a base field
+tests/qapi-schema/flat-union-no-base.json:9: Flat union 'TestUnion' must have a base field
@@ -1,10 +1,12 @@
+# FIXME: flat unions should require a base
+# TODO: simple unions should be able to use an enum discriminator
{ 'type': 'TestTypeA',
'data': { 'string': 'str' } }
-
{ 'type': 'TestTypeB',
'data': { 'integer': 'int' } }
-
+{ 'enum': 'Enum',
+ 'data': [ 'value1', 'value2' ] }
{ 'union': 'TestUnion',
- 'discriminator': 'enum1',
+ 'discriminator': 'Enum',
'data': { 'value1': 'TestTypeA',
'value2': 'TestTypeB' } }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,10 @@
+# FIXME: we should require the discriminator to be non-optional
+{ 'enum': 'Enum', 'data': [ 'one', 'two' ] }
+{ 'type': 'Base',
+ 'data': { '*switch': 'Enum' } }
+{ 'type': 'Branch', 'data': { 'name': 'str' } }
+{ 'union': 'MyUnion',
+ 'base': 'Base',
+ 'discriminator': '*switch',
+ 'data': { 'one': 'Branch',
+ 'two': 'Branch' } }
new file mode 100644
@@ -0,0 +1,7 @@
+[OrderedDict([('enum', 'Enum'), ('data', ['one', 'two'])]),
+ OrderedDict([('type', 'Base'), ('data', OrderedDict([('*switch', 'Enum')]))]),
+ OrderedDict([('type', 'Branch'), ('data', OrderedDict([('name', 'str')]))]),
+ OrderedDict([('union', 'MyUnion'), ('base', 'Base'), ('discriminator', '*switch'), ('data', OrderedDict([('one', 'Branch'), ('two', 'Branch')]))])]
+[{'enum_name': 'Enum', 'enum_values': ['one', 'two']}]
+[OrderedDict([('type', 'Base'), ('data', OrderedDict([('*switch', 'Enum')]))]),
+ OrderedDict([('type', 'Branch'), ('data', OrderedDict([('name', 'str')]))])]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,8 @@
+# FIXME: we should reject normal unions where branches would collide in C
+{ 'type': 'One',
+ 'data': { 'string': 'str' } }
+{ 'type': 'Two',
+ 'data': { 'number': 'int' } }
+{ 'union': 'MyUnion',
+ 'data': { 'one': 'One',
+ 'ONE': 'Two' } }
new file mode 100644
@@ -0,0 +1,6 @@
+[OrderedDict([('type', 'One'), ('data', OrderedDict([('string', 'str')]))]),
+ OrderedDict([('type', 'Two'), ('data', OrderedDict([('number', 'int')]))]),
+ OrderedDict([('union', 'MyUnion'), ('data', OrderedDict([('one', 'One'), ('ONE', 'Two')]))])]
+[{'enum_name': 'MyUnionKind', 'enum_values': None}]
+[OrderedDict([('type', 'One'), ('data', OrderedDict([('string', 'str')]))]),
+ OrderedDict([('type', 'Two'), ('data', OrderedDict([('number', 'int')]))])]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,14 @@
+# FIXME: we should reject simple unions with a base
+{ 'type': 'TestTypeA',
+ 'data': { 'string': 'str' } }
+
+{ 'type': 'TestTypeB',
+ 'data': { 'integer': 'int' } }
+
+{ 'type': 'Base',
+ 'data': { 'string': 'str' } }
+
+{ 'union': 'TestUnion',
+ 'base': 'Base',
+ 'data': { 'value1': 'TestTypeA',
+ 'value2': 'TestTypeB' } }
new file mode 100644
@@ -0,0 +1,8 @@
+[OrderedDict([('type', 'TestTypeA'), ('data', OrderedDict([('string', 'str')]))]),
+ OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('type', 'Base'), ('data', OrderedDict([('string', 'str')]))]),
+ OrderedDict([('union', 'TestUnion'), ('base', 'Base'), ('data', OrderedDict([('value1', 'TestTypeA'), ('value2', 'TestTypeB')]))])]
+[{'enum_name': 'TestUnionKind', 'enum_values': None}]
+[OrderedDict([('type', 'TestTypeA'), ('data', OrderedDict([('string', 'str')]))]),
+ OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('type', 'Base'), ('data', OrderedDict([('string', 'str')]))])]
@@ -1 +1 @@
-tests/qapi-schema/union-invalid-base.json:7: Base 'TestBaseWrong' is not a valid type
+tests/qapi-schema/union-invalid-base.json:8: Base 'int' is not a valid type
@@ -1,3 +1,4 @@
+# a union base type must be a struct
{ 'type': 'TestTypeA',
'data': { 'string': 'str' } }
@@ -5,6 +6,7 @@
'data': { 'integer': 'int' } }
{ 'union': 'TestUnion',
- 'base': 'TestBaseWrong',
+ 'base': 'int',
+ 'discriminator': 'int',
'data': { 'value1': 'TestTypeA',
'value2': 'TestTypeB' } }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,3 @@
+# FIXME: we should reject 'max' branch in a union, for collision with C enum
+{ 'union': 'Union',
+ 'data': { 'max': 'int' } }
new file mode 100644
@@ -0,0 +1,3 @@
+[OrderedDict([('union', 'Union'), ('data', OrderedDict([('max', 'int')]))])]
+[{'enum_name': 'UnionKind', 'enum_values': None}]
+[]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,2 @@
+# FIXME: union branches cannot be optional
+{ 'union': 'Union', 'data': { '*a': 'int', 'b': 'str' } }
new file mode 100644
@@ -0,0 +1,3 @@
+[OrderedDict([('union', 'Union'), ('data', OrderedDict([('*a', 'int'), ('b', 'str')]))])]
+[{'enum_name': 'UnionKind', 'enum_values': None}]
+[]
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
+0
new file mode 100644
@@ -0,0 +1,3 @@
+# FIXME: we should reject a union with unknown type in branch
+{ 'union': 'Union',
+ 'data': { 'unknown': 'MissingType' } }
new file mode 100644
@@ -0,0 +1,3 @@
+[OrderedDict([('union', 'Union'), ('data', OrderedDict([('unknown', 'MissingType')]))])]
+[{'enum_name': 'UnionKind', 'enum_values': None}]
+[]
Demonstrate that the qapi generator doesn't deal well with unions that aren't up to par. Later patches will update the expected reseults as the generator is made stricter. A few tests work as planned, but most show poor or missing error messages. Of particular note, qapi-code-gen.txt documents 'base' only for flat unions, but the tests here demonstrate that we currently allow a 'base' to a simple union, although it is exercised only in the testsuite. Later patches will remove this undocumented feature, to give us more flexibility in adding other future extensions to union types. For example, one possible extension is the idea of a type-safe simple enum, where added fields tie the discriminator to a user-defined enum type rather than creating an implicit enum from the names in 'data'. But adding such safety on top of a simple enum with a base type could look ambiguous with a flat enum; besides, the documentation also mentions how any simple union can be represented by an equivalent flat union. So it will be simpler to just outlaw support for something we aren't using. Signed-off-by: Eric Blake <eblake@redhat.com> --- v6: improve the commit message; add flat-union-base-star, flat-union-inline, flat-union-int-branch, and flat-union-branch-clash tests; fix comments and code in alternate-array, flat-union-bad-base, flat-union-no-base, and union-base-no-discriminator; drop trailing blank line in alternate-conflict-string; drop TABs in tests --- tests/Makefile | 14 +++++++++++--- tests/qapi-schema/alternate-array.err | 0 tests/qapi-schema/alternate-array.exit | 1 + tests/qapi-schema/alternate-array.json | 8 ++++++++ tests/qapi-schema/alternate-array.out | 4 ++++ tests/qapi-schema/alternate-base.err | 0 tests/qapi-schema/alternate-base.exit | 1 + tests/qapi-schema/alternate-base.json | 7 +++++++ tests/qapi-schema/alternate-base.out | 4 ++++ tests/qapi-schema/alternate-clash.err | 0 tests/qapi-schema/alternate-clash.exit | 1 + tests/qapi-schema/alternate-clash.json | 4 ++++ tests/qapi-schema/alternate-clash.out | 3 +++ tests/qapi-schema/alternate-conflict-dict.err | 0 tests/qapi-schema/alternate-conflict-dict.exit | 1 + tests/qapi-schema/alternate-conflict-dict.json | 9 +++++++++ tests/qapi-schema/alternate-conflict-dict.out | 6 ++++++ tests/qapi-schema/alternate-conflict-string.err | 0 tests/qapi-schema/alternate-conflict-string.exit | 1 + tests/qapi-schema/alternate-conflict-string.json | 7 +++++++ tests/qapi-schema/alternate-conflict-string.out | 5 +++++ tests/qapi-schema/alternate-good.err | 0 tests/qapi-schema/alternate-good.exit | 1 + tests/qapi-schema/alternate-good.json | 10 ++++++++++ tests/qapi-schema/alternate-good.out | 6 ++++++ tests/qapi-schema/alternate-nested.err | 0 tests/qapi-schema/alternate-nested.exit | 1 + tests/qapi-schema/alternate-nested.json | 7 +++++++ tests/qapi-schema/alternate-nested.out | 5 +++++ tests/qapi-schema/alternate-unknown.err | 0 tests/qapi-schema/alternate-unknown.exit | 1 + tests/qapi-schema/alternate-unknown.json | 4 ++++ tests/qapi-schema/alternate-unknown.out | 3 +++ tests/qapi-schema/flat-union-bad-base.err | 1 + tests/qapi-schema/flat-union-bad-base.exit | 1 + tests/qapi-schema/flat-union-bad-base.json | 13 +++++++++++++ tests/qapi-schema/flat-union-bad-base.out | 0 tests/qapi-schema/flat-union-bad-discriminator.err | 0 tests/qapi-schema/flat-union-bad-discriminator.exit | 1 + tests/qapi-schema/flat-union-bad-discriminator.json | 14 ++++++++++++++ tests/qapi-schema/flat-union-bad-discriminator.out | 10 ++++++++++ tests/qapi-schema/flat-union-base-star.err | 1 + tests/qapi-schema/flat-union-base-star.exit | 1 + tests/qapi-schema/flat-union-base-star.json | 12 ++++++++++++ tests/qapi-schema/flat-union-base-star.out | 0 tests/qapi-schema/flat-union-base-union.err | 1 + tests/qapi-schema/flat-union-base-union.exit | 1 + tests/qapi-schema/flat-union-base-union.json | 15 +++++++++++++++ tests/qapi-schema/flat-union-base-union.out | 0 tests/qapi-schema/flat-union-branch-clash.err | 0 tests/qapi-schema/flat-union-branch-clash.exit | 1 + tests/qapi-schema/flat-union-branch-clash.json | 14 ++++++++++++++ tests/qapi-schema/flat-union-branch-clash.out | 9 +++++++++ tests/qapi-schema/flat-union-inline.err | 1 + tests/qapi-schema/flat-union-inline.exit | 1 + tests/qapi-schema/flat-union-inline.json | 11 +++++++++++ tests/qapi-schema/flat-union-inline.out | 0 tests/qapi-schema/flat-union-int-branch.err | 0 tests/qapi-schema/flat-union-int-branch.exit | 1 + tests/qapi-schema/flat-union-int-branch.json | 12 ++++++++++++ tests/qapi-schema/flat-union-int-branch.out | 7 +++++++ tests/qapi-schema/flat-union-no-base.err | 2 +- tests/qapi-schema/flat-union-no-base.json | 8 +++++--- tests/qapi-schema/flat-union-optional-discriminator.err | 0 tests/qapi-schema/flat-union-optional-discriminator.exit | 1 + tests/qapi-schema/flat-union-optional-discriminator.json | 10 ++++++++++ tests/qapi-schema/flat-union-optional-discriminator.out | 7 +++++++ tests/qapi-schema/union-bad-branch.err | 0 tests/qapi-schema/union-bad-branch.exit | 1 + tests/qapi-schema/union-bad-branch.json | 8 ++++++++ tests/qapi-schema/union-bad-branch.out | 6 ++++++ tests/qapi-schema/union-base-no-discriminator.err | 0 tests/qapi-schema/union-base-no-discriminator.exit | 1 + tests/qapi-schema/union-base-no-discriminator.json | 14 ++++++++++++++ tests/qapi-schema/union-base-no-discriminator.out | 8 ++++++++ tests/qapi-schema/union-invalid-base.err | 2 +- tests/qapi-schema/union-invalid-base.json | 4 +++- tests/qapi-schema/union-max.err | 0 tests/qapi-schema/union-max.exit | 1 + tests/qapi-schema/union-max.json | 3 +++ tests/qapi-schema/union-max.out | 3 +++ tests/qapi-schema/union-optional-branch.err | 0 tests/qapi-schema/union-optional-branch.exit | 1 + tests/qapi-schema/union-optional-branch.json | 2 ++ tests/qapi-schema/union-optional-branch.out | 3 +++ tests/qapi-schema/union-unknown.err | 0 tests/qapi-schema/union-unknown.exit | 1 + tests/qapi-schema/union-unknown.json | 3 +++ tests/qapi-schema/union-unknown.out | 3 +++ 89 files changed, 325 insertions(+), 9 deletions(-) create mode 100644 tests/qapi-schema/alternate-array.err create mode 100644 tests/qapi-schema/alternate-array.exit create mode 100644 tests/qapi-schema/alternate-array.json create mode 100644 tests/qapi-schema/alternate-array.out create mode 100644 tests/qapi-schema/alternate-base.err create mode 100644 tests/qapi-schema/alternate-base.exit create mode 100644 tests/qapi-schema/alternate-base.json create mode 100644 tests/qapi-schema/alternate-base.out create mode 100644 tests/qapi-schema/alternate-clash.err create mode 100644 tests/qapi-schema/alternate-clash.exit create mode 100644 tests/qapi-schema/alternate-clash.json create mode 100644 tests/qapi-schema/alternate-clash.out create mode 100644 tests/qapi-schema/alternate-conflict-dict.err create mode 100644 tests/qapi-schema/alternate-conflict-dict.exit create mode 100644 tests/qapi-schema/alternate-conflict-dict.json create mode 100644 tests/qapi-schema/alternate-conflict-dict.out create mode 100644 tests/qapi-schema/alternate-conflict-string.err create mode 100644 tests/qapi-schema/alternate-conflict-string.exit create mode 100644 tests/qapi-schema/alternate-conflict-string.json create mode 100644 tests/qapi-schema/alternate-conflict-string.out create mode 100644 tests/qapi-schema/alternate-good.err create mode 100644 tests/qapi-schema/alternate-good.exit create mode 100644 tests/qapi-schema/alternate-good.json create mode 100644 tests/qapi-schema/alternate-good.out create mode 100644 tests/qapi-schema/alternate-nested.err create mode 100644 tests/qapi-schema/alternate-nested.exit create mode 100644 tests/qapi-schema/alternate-nested.json create mode 100644 tests/qapi-schema/alternate-nested.out create mode 100644 tests/qapi-schema/alternate-unknown.err create mode 100644 tests/qapi-schema/alternate-unknown.exit create mode 100644 tests/qapi-schema/alternate-unknown.json create mode 100644 tests/qapi-schema/alternate-unknown.out create mode 100644 tests/qapi-schema/flat-union-bad-base.err create mode 100644 tests/qapi-schema/flat-union-bad-base.exit create mode 100644 tests/qapi-schema/flat-union-bad-base.json create mode 100644 tests/qapi-schema/flat-union-bad-base.out create mode 100644 tests/qapi-schema/flat-union-bad-discriminator.err create mode 100644 tests/qapi-schema/flat-union-bad-discriminator.exit create mode 100644 tests/qapi-schema/flat-union-bad-discriminator.json create mode 100644 tests/qapi-schema/flat-union-bad-discriminator.out create mode 100644 tests/qapi-schema/flat-union-base-star.err create mode 100644 tests/qapi-schema/flat-union-base-star.exit create mode 100644 tests/qapi-schema/flat-union-base-star.json create mode 100644 tests/qapi-schema/flat-union-base-star.out create mode 100644 tests/qapi-schema/flat-union-base-union.err create mode 100644 tests/qapi-schema/flat-union-base-union.exit create mode 100644 tests/qapi-schema/flat-union-base-union.json create mode 100644 tests/qapi-schema/flat-union-base-union.out create mode 100644 tests/qapi-schema/flat-union-branch-clash.err create mode 100644 tests/qapi-schema/flat-union-branch-clash.exit create mode 100644 tests/qapi-schema/flat-union-branch-clash.json create mode 100644 tests/qapi-schema/flat-union-branch-clash.out create mode 100644 tests/qapi-schema/flat-union-inline.err create mode 100644 tests/qapi-schema/flat-union-inline.exit create mode 100644 tests/qapi-schema/flat-union-inline.json create mode 100644 tests/qapi-schema/flat-union-inline.out create mode 100644 tests/qapi-schema/flat-union-int-branch.err create mode 100644 tests/qapi-schema/flat-union-int-branch.exit create mode 100644 tests/qapi-schema/flat-union-int-branch.json create mode 100644 tests/qapi-schema/flat-union-int-branch.out create mode 100644 tests/qapi-schema/flat-union-optional-discriminator.err create mode 100644 tests/qapi-schema/flat-union-optional-discriminator.exit create mode 100644 tests/qapi-schema/flat-union-optional-discriminator.json create mode 100644 tests/qapi-schema/flat-union-optional-discriminator.out create mode 100644 tests/qapi-schema/union-bad-branch.err create mode 100644 tests/qapi-schema/union-bad-branch.exit create mode 100644 tests/qapi-schema/union-bad-branch.json create mode 100644 tests/qapi-schema/union-bad-branch.out create mode 100644 tests/qapi-schema/union-base-no-discriminator.err create mode 100644 tests/qapi-schema/union-base-no-discriminator.exit create mode 100644 tests/qapi-schema/union-base-no-discriminator.json create mode 100644 tests/qapi-schema/union-base-no-discriminator.out create mode 100644 tests/qapi-schema/union-max.err create mode 100644 tests/qapi-schema/union-max.exit create mode 100644 tests/qapi-schema/union-max.json create mode 100644 tests/qapi-schema/union-max.out create mode 100644 tests/qapi-schema/union-optional-branch.err create mode 100644 tests/qapi-schema/union-optional-branch.exit create mode 100644 tests/qapi-schema/union-optional-branch.json create mode 100644 tests/qapi-schema/union-optional-branch.out create mode 100644 tests/qapi-schema/union-unknown.err create mode 100644 tests/qapi-schema/union-unknown.exit create mode 100644 tests/qapi-schema/union-unknown.json create mode 100644 tests/qapi-schema/union-unknown.out