Skip to content

Commit

Permalink
fix: handle nested interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Tienisto committed Feb 27, 2024
1 parent 8a44d2f commit ba487b7
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 2 deletions.
11 changes: 9 additions & 2 deletions slang/lib/builder/builder/translation_model_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,8 @@ void _applyInterfaceAndGenericsRecursive({
if (interface != null) {
curr.setInterface(interface);

// in case this interface is new
// Save the interface in the collection
// (might override existing interface of the same name)
interfaceCollection.resultInterfaces[interface.name] = interface;
}
}
Expand Down Expand Up @@ -783,7 +784,13 @@ Set<InterfaceAttribute> _parseAttributes(ObjectNode node) {
returnType = 'List<${child.genericType}>';
parameters = {}; // lists never have parameters
} else if (child is ObjectNode) {
returnType = 'Map<String, ${child.genericType}>';
if (child.interface != null) {
returnType = child.interface!.name;
} else if (child.isMap) {
returnType = 'Map<String, ${child.genericType}>';
} else {
returnType = 'UnsupportedType';
}
parameters = {}; // objects never have parameters
} else if (child is PluralNode) {
returnType = child.rich ? 'TextSpan' : 'String';
Expand Down
122 changes: 122 additions & 0 deletions slang/test/unit/builder/translation_model_builder_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -209,5 +209,127 @@ void main() {

expect(result.contexts, []);
});

test('Should handle nested interfaces specified via modifier', () {
final resultUsingModifiers = TranslationModelBuilder.build(
buildConfig: RawConfig.defaultConfig.toBuildModelConfig(),
map: {
'myContainer(interface=MyInterface)': {
'firstItem': {
'a': 'A1',
'nestedItem(singleInterface=MyNestedInterface)': {
'z': 'Z',
},
},
'secondItem': {
'a': 'A2',
'nestedItem(singleInterface=MyNestedInterface)': {
'z': 'Z',
},
},
'thirdItem': {
'a': 'A3',
'nestedItem(singleInterface=MyNestedInterface)': {
'z': 'Z',
},
},
}
},
localeDebug: RawConfig.defaultBaseLocale,
);

_checkInterfaceResult(resultUsingModifiers);
});

test('Should handle nested interface specified via config', () {
final resultUsingConfig = TranslationModelBuilder.build(
buildConfig: RawConfig.defaultConfig.copyWith(
interfaces: [
InterfaceConfig(
name: 'MyNestedInterface',
paths: [],
attributes: {
InterfaceAttribute(
attributeName: 'z',
returnType: 'String',
parameters: {},
optional: false,
),
},
),
],
).toBuildModelConfig(),
map: {
'myContainer(interface=MyInterface)': {
'firstItem': {
'a': 'A1',
'nestedItem': {
'z': 'Z',
},
},
'secondItem': {
'a': 'A2',
'nestedItem': {
'z': 'Z',
},
},
'thirdItem': {
'a': 'A3',
'nestedItem': {
'z': 'Z',
},
},
}
},
localeDebug: RawConfig.defaultBaseLocale,
);

_checkInterfaceResult(resultUsingConfig);
});
});
}

void _checkInterfaceResult(BuildModelResult result) {
final interfaces = result.interfaces;
expect(interfaces.length, 2);
expect(interfaces[0].name, 'MyNestedInterface');
expect(interfaces[0].attributes.length, 1);
expect(interfaces[0].attributes.first.attributeName, 'z');
expect(interfaces[1].name, 'MyInterface');
expect(interfaces[1].attributes.length, 2);
expect(interfaces[1].attributes.first.attributeName, 'a');
expect(interfaces[1].attributes.last.attributeName, 'nestedItem');

final objectNode = result.root.entries['myContainer'] as ObjectNode;
expect(objectNode.interface, isNull);

expect(objectNode.entries['firstItem'], isA<ObjectNode>());
expect(objectNode.entries['secondItem'], isA<ObjectNode>());
expect(objectNode.entries['thirdItem'], isA<ObjectNode>());

expect((objectNode.entries['firstItem'] as ObjectNode).interface?.name,
'MyInterface');
expect((objectNode.entries['secondItem'] as ObjectNode).interface?.name,
'MyInterface');
expect((objectNode.entries['thirdItem'] as ObjectNode).interface?.name,
'MyInterface');

expect(
((objectNode.entries['firstItem'] as ObjectNode).entries['nestedItem']
as ObjectNode)
.interface
?.name,
'MyNestedInterface');
expect(
((objectNode.entries['secondItem'] as ObjectNode).entries['nestedItem']
as ObjectNode)
.interface
?.name,
'MyNestedInterface');
expect(
((objectNode.entries['thirdItem'] as ObjectNode).entries['nestedItem']
as ObjectNode)
.interface
?.name,
'MyNestedInterface');
}

0 comments on commit ba487b7

Please sign in to comment.