Skip to content

Commit 328c9da

Browse files
committed
feat: added --enum-name-mappings support
This allows to change names of enum properties. Especially needed for enums that has `name` as a property which is reserved in `dio` etc Also fixes #91
1 parent 99f6bec commit 328c9da

File tree

9 files changed

+348
-58
lines changed

9 files changed

+348
-58
lines changed

openapi-generator-annotations/lib/src/openapi_generator_annotations_base.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ class Openapi {
9393
/// --name-mappings
9494
final Map<String, String>? nameMappings;
9595

96+
/// Specifies mappings between the enum name and the new name in the
97+
/// format of enum_name=AnotherName,enum_name2=OtherName2. You can also
98+
/// have multiple occurrences of this option.
99+
100+
/// --enum-name-mappings
101+
final Map<String, String>? enumNameMappings;
102+
96103
/// specifies mappings between a given class and the import that should
97104
/// be used for that class in the format of type=import,type=import. You
98105
/// can also have multiple occurrences of this option.
@@ -163,6 +170,7 @@ class Openapi {
163170
this.cleanSubOutputDirectory,
164171
this.typeMappings,
165172
this.nameMappings,
173+
this.enumNameMappings,
166174
this.importMappings,
167175
this.reservedWordsMappings,
168176
this.inlineSchemaNameMappings,
@@ -197,7 +205,7 @@ class Openapi {
197205
}
198206
if (cleanSubOutputDirectory != null) {
199207
buffer.writeln(
200-
' cleanSubOutputDirectory: [${cleanSubOutputDirectory!.join(", ")}],');
208+
' cleanSubOutputDirectory: ["${cleanSubOutputDirectory!.join('", "')}"],');
201209
}
202210
if (skipSpecValidation != null) {
203211
buffer.writeln(' skipSpecValidation: $skipSpecValidation,');
@@ -218,6 +226,9 @@ class Openapi {
218226
if (nameMappings != null) {
219227
buffer.writeln(' nameMappings: ${_formatMap(nameMappings!)},');
220228
}
229+
if (enumNameMappings != null) {
230+
buffer.writeln(' enumNameMappings: ${_formatMap(enumNameMappings!)},');
231+
}
221232
if (importMappings != null) {
222233
buffer.writeln(' importMappings: ${_formatMap(importMappings!)},');
223234
}

openapi-generator-annotations/test/openapi_generator_annotations_test.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ void main() {
2929
expect(props.projectPubspecPath, isNull);
3030
expect(props.debugLogging, isFalse);
3131
expect(props.nameMappings, isNull);
32+
expect(props.enumNameMappings, isNull);
3233
expect(props.skipIfSpecIsUnchanged, isTrue);
3334
});
3435
group('NextGen', () {
@@ -316,6 +317,16 @@ void main() {
316317
contains('nameMappings: {\'name\':\'customName\'}'));
317318
});
318319

320+
test('should include enumNameMappings when set', () {
321+
final openapi = Openapi(
322+
enumNameMappings: {'name': 'customName'},
323+
inputSpec: InputSpec(path: 'example_path'),
324+
generatorName: Generator.dart,
325+
);
326+
expect(openapi.toString().replaceAll('\n', ''),
327+
contains('enumNameMappings: {\'name\':\'customName\'}'));
328+
});
329+
319330
test('should include importMappings when set', () {
320331
final openapi = Openapi(
321332
importMappings: {

openapi-generator-cli/bin/main.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ Future<Map<String, dynamic>> loadOrCreateConfig(String configPath) async {
6060

6161
void _logOutput(String message) {
6262
stdout.writeln(message);
63-
print(message);
6463
}
6564

6665
/// Constructs the default OpenAPI Generator JAR file download URL based on the version

openapi-generator/lib/src/models/generator_arguments.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ class GeneratorArguments {
8686
/// Defines mappings between OpenAPI spec var/param/model and generated code.
8787
final Map<String, String>? nameMappings;
8888

89+
final Map<String, String>? enumNameMappings;
90+
8991
/// Adds reserved words mappings.
9092
///
9193
/// Supported by [Generator.dio] & [Generator.dioAlt] generators.
@@ -106,6 +108,7 @@ class GeneratorArguments {
106108
annotations.readPropertyOrDefault('generatorName', Generator.dart),
107109
typeMappings = annotations.readPropertyOrNull('typeMappings'),
108110
nameMappings = annotations.readPropertyOrNull('nameMappings'),
111+
enumNameMappings = annotations.readPropertyOrNull('enumNameMappings'),
109112
importMappings = annotations.readPropertyOrNull('importMappings'),
110113
reservedWordsMappings =
111114
annotations.readPropertyOrNull('reservedWordsMappings'),
@@ -192,6 +195,8 @@ class GeneratorArguments {
192195
'--type-mappings=${typeMappings!.entries.fold('', foldStringMap())}',
193196
if (nameMappings?.isNotEmpty ?? false)
194197
'--name-mappings=${nameMappings!.entries.fold('', foldStringMap())}',
198+
if (enumNameMappings?.isNotEmpty ?? false)
199+
'--enum-name-mappings=${enumNameMappings!.entries.fold('', foldStringMap())}',
195200
if (inlineSchemaOptions != null)
196201
'--inline-schema-options=${inlineSchemaOptions!.toMap().entries.fold('', foldStringMap(keyModifier: convertToPropertyKey))}',
197202
if (additionalProperties != null)

openapi-generator/lib/src/openapi_generator_runner.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ class OpenapiGenerator extends GeneratorForAnnotation<annots.Openapi> {
392392
);
393393

394394
if (results.exitCode != 0) {
395-
print('===> args ${await args.jarArgs}');
395+
print('===> args ${args.jarArgs}');
396396
return Future.error(
397397
OutputMessage(
398398
message: 'Failed to generate source code. Build Command output:',

openapi-generator/test/builder_test.dart

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import 'dart:async';
21
import 'dart:convert';
32
import 'dart:io';
43

@@ -38,40 +37,58 @@ void main() {
3837
});
3938

4039
test('to generate command with import and type mappings', () async {
41-
final annotations = await getReaderForAnnotation('''
42-
@Openapi(
43-
inputSpec: InputSpec(path: '../openapi-spec.yaml'),
44-
typeMappings: {'int-or-string':'IntOrString'},
45-
importMappings: {'IntOrString':'./int_or_string.dart'},
46-
generatorName: Generator.dio,
47-
outputDirectory: '${testSpecPath}output',
48-
)
49-
''');
50-
final args = GeneratorArguments(annotations: annotations);
40+
final annotations = Openapi(
41+
inputSpec: InputSpec(path: '../openapi-spec.yaml'),
42+
typeMappings: {'int-or-string': 'IntOrString'},
43+
importMappings: {'IntOrString': './int_or_string.dart'},
44+
generatorName: Generator.dio,
45+
outputDirectory: '${testSpecPath}output',
46+
);
47+
final args = await getArguments(annotations);
5148
expect(
52-
(await args.jarArgs).join(' '),
49+
args.jarArgs.join(' '),
5350
contains(
5451
'generate -o=${testSpecPath}output -i=../openapi-spec.yaml -g=dart-dio --import-mappings=IntOrString=./int_or_string.dart --type-mappings=int-or-string=IntOrString'));
5552
});
5653

5754
test('to generate command with inline schema mappings', () async {
58-
final annotations = await getReaderForAnnotation('''
59-
@Openapi(
60-
inputSpec: InputSpec(path: '../openapi-spec.yaml'),
61-
typeMappings: {'int-or-string':'IntOrString'},
62-
inlineSchemaNameMappings: {'inline_object_2':'SomethingMapped','inline_object_4':'nothing_new'},
63-
generatorName: Generator.dio,
64-
outputDirectory: '${testSpecPath}output',
65-
)
66-
''');
67-
final args = GeneratorArguments(annotations: annotations);
55+
final annotation = Openapi(
56+
inputSpec: InputSpec(path: '../openapi-spec.yaml'),
57+
typeMappings: {'int-or-string': 'IntOrString'},
58+
inlineSchemaNameMappings: {
59+
'inline_object_2': 'SomethingMapped',
60+
'inline_object_4': 'nothing_new'
61+
},
62+
generatorName: Generator.dio,
63+
outputDirectory: '${testSpecPath}output',
64+
);
65+
final args = await getArguments(annotation);
6866
expect(
69-
(await args.jarArgs).join(' '),
67+
args.jarArgs.join(' '),
7068
equals('''
7169
generate -o=${testSpecPath}output -i=../openapi-spec.yaml -g=dart-dio --inline-schema-name-mappings=inline_object_2=SomethingMapped,inline_object_4=nothing_new --type-mappings=int-or-string=IntOrString
7270
'''
7371
.trim()));
7472
});
73+
74+
test('to generate command with enum name mappings', () async {
75+
final annotation = Openapi(
76+
inputSpec: InputSpec(path: '../openapi-spec.yaml'),
77+
typeMappings: {'int-or-string': 'IntOrString'},
78+
inlineSchemaNameMappings: {
79+
'inline_object_2': 'SomethingMapped',
80+
'inline_object_4': 'nothing_new'
81+
},
82+
enumNameMappings: {'name': 'name_', 'inline_object_4': 'nothing_new'},
83+
generatorName: Generator.dio,
84+
outputDirectory: '${testSpecPath}output',
85+
);
86+
final args = await getArguments(annotation);
87+
expect(
88+
args.jarArgs,
89+
contains(
90+
'--enum-name-mappings=name=name_,inline_object_4=nothing_new'));
91+
});
7592
});
7693

7794
group('generator dioAlt', () {
@@ -110,18 +127,16 @@ class TestClassConfig extends OpenapiGeneratorConfig {}
110127

111128
test('to generate command with import and type mappings for dioAlt',
112129
() async {
113-
var annots = await getReaderForAnnotation('''
114-
@Openapi(
115-
inputSpec: InputSpec(path:'../openapi-spec.yaml'),
116-
typeMappings: {'int-or-string':'IntOrString'},
117-
importMappings: {'IntOrString':'./int_or_string.dart'},
118-
generatorName: Generator.dioAlt,
119-
outputDirectory: '${testSpecPath}output',
120-
)
121-
''');
122-
var args = GeneratorArguments(annotations: annots);
130+
var annot = Openapi(
131+
inputSpec: InputSpec(path: '../openapi-spec.yaml'),
132+
typeMappings: {'int-or-string': 'IntOrString'},
133+
importMappings: {'IntOrString': './int_or_string.dart'},
134+
generatorName: Generator.dioAlt,
135+
outputDirectory: '${testSpecPath}output',
136+
);
137+
var args = await getArguments(annot);
123138
expect(
124-
(await args.jarArgs).join(' '),
139+
args.jarArgs.join(' '),
125140
equals(
126141
'generate -o=${testSpecPath}output -i=../openapi-spec.yaml -g=dart2-api --import-mappings=IntOrString=./int_or_string.dart --type-mappings=int-or-string=IntOrString'));
127142
});
@@ -587,19 +602,3 @@ class TestClassConfig extends OpenapiGeneratorConfig {}
587602
});
588603
});
589604
}
590-
591-
Future<ConstantReader> getReaderForAnnotation(String annotationDef) async {
592-
final annotations = (await resolveSource('''
593-
library test_lib;
594-
import 'package:openapi_generator_annotations/openapi_generator_annotations.dart';
595-
596-
$annotationDef
597-
class TestClassConfig {}
598-
''',
599-
(resolver) async => (await resolver.findLibraryByName('test_lib'))!))
600-
.getClass('TestClassConfig')!
601-
.metadata
602-
.map((e) => ConstantReader(e.computeConstantValue()!))
603-
.first;
604-
return annotations;
605-
}

openapi-generator/test/github_issues_test.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:io';
22

33
import 'package:openapi_generator/src/process_runner.dart';
4+
import 'package:openapi_generator_annotations/openapi_generator_annotations.dart';
45
import 'package:path/path.dart' as path;
56
import 'package:test/expect.dart';
67
import 'package:test/scaffolding.dart';
@@ -26,6 +27,53 @@ void main() {
2627
// }
2728
// });
2829

30+
group('#91', () {
31+
var issueNumber = '91';
32+
var parentFolder = path.join(testSpecPath, 'issue', issueNumber);
33+
var workingDirectory = path.join(parentFolder, 'output');
34+
setUpAll(
35+
() {
36+
var workingDirectory = path.join(parentFolder, 'output');
37+
cleanup(workingDirectory);
38+
},
39+
);
40+
test(
41+
'[dart] Test that broken code is not generated for OPENAPI tictactoe example',
42+
() async {
43+
var inputSpecFile =
44+
File('$parentFolder/github_issue_#$issueNumber.json');
45+
var generatedOutput = await generateFromAnnotation(
46+
Openapi(
47+
additionalProperties: AdditionalProperties(
48+
pubName: 'tictactoe_api',
49+
pubAuthor: 'Jon Doe',
50+
pubAuthorEmail: 'me@example.com'),
51+
inputSpec: InputSpec(path: inputSpecFile.path),
52+
generatorName: Generator.dart,
53+
cleanSubOutputDirectory: [
54+
'./test/specs/issue/$issueNumber/output'
55+
],
56+
cachePath: './test/specs/issue/$issueNumber/output/cache.json',
57+
outputDirectory: './test/specs/issue/$issueNumber/output'),
58+
process: processRunner,
59+
);
60+
61+
expect(generatedOutput,
62+
contains('Skipping source gen because generator does not need it.'),
63+
reason: generatedOutput);
64+
expect(generatedOutput, contains('Successfully formatted code.'),
65+
reason: generatedOutput);
66+
var analyzeResult = await Process.run(
67+
'dart',
68+
['analyze'],
69+
workingDirectory: workingDirectory,
70+
);
71+
expect(analyzeResult.exitCode, 0,
72+
reason: '${analyzeResult.stdout}\n\n${analyzeResult.stderr}');
73+
cleanup(workingDirectory);
74+
});
75+
});
76+
2977
group('#114', () {
3078
var issueNumber = '114';
3179
var parentFolder = path.join(testSpecPath, 'issue', issueNumber);

0 commit comments

Comments
 (0)