Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions modules/openapi-generator/src/main/resources/dart2/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,23 @@ class {{{classname}}} {
{{^required}}
if ({{{paramName}}} != null) {
{{/required}}
{{#isMap}}
{{#isExplode}}
{{^isDeepObject}}
// form style explodes an object into one query parameter per entry, keyed by the property name alone
{{#isFreeFormObject}}({{{paramName}}} as Map){{/isFreeFormObject}}{{^isFreeFormObject}}{{{paramName}}}{{/isFreeFormObject}}.forEach((entryKey, entryValue) => queryParams.addAll(_queryParams('', entryKey.toString(), entryValue)));
{{/isDeepObject}}
{{#isDeepObject}}
queryParams.addAll(_queryParams('{{{collectionFormat}}}', '{{{baseName}}}', {{{paramName}}}));
{{/isDeepObject}}
{{/isExplode}}
{{^isExplode}}
queryParams.addAll(_queryParams('{{{collectionFormat}}}', '{{{baseName}}}', {{{paramName}}}));
{{/isExplode}}
{{/isMap}}
{{^isMap}}
queryParams.addAll(_queryParams('{{{collectionFormat}}}', '{{{baseName}}}', {{{paramName}}}));
{{/isMap}}
{{^required}}
}
{{/required}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,33 @@ public void testObjectArrayDoesNotUseListFromJson() throws Exception {
TestUtils.assertFileContains(modelFile.toPath(), "cast<Object>");
}

@Test(description = "Verify an object query parameter is exploded, whether or not it declares its properties")
public void testExplodedObjectQueryParameter() throws Exception {
List<File> files = generateDartNativeFromSpec(
"src/test/resources/3_0/exploded-object-query-param.yaml");

File apiFile = files.stream()
.filter(f -> f.getName().equals("default_api.dart"))
.findFirst()
.orElseThrow(() -> new AssertionError("default_api.dart not found in generated files"));

// form style with explode - the default - puts every entry on the wire under its own
// property name. Handing the whole map to _queryParams stringifies it with
// Map.toString(), which is what used to happen.
TestUtils.assertFileContains(apiFile.toPath(),
"(filter as Map).forEach((entryKey, entryValue) => queryParams.addAll(_queryParams('', entryKey.toString(), entryValue)));");
TestUtils.assertFileNotContains(apiFile.toPath(), "_queryParams('', 'filter', filter)");

// a declared map behaves the same way, and needs no cast
TestUtils.assertFileContains(apiFile.toPath(),
"typedFilter.forEach((entryKey, entryValue) => queryParams.addAll(_queryParams('', entryKey.toString(), entryValue)));");

// deepObject and form without explode both keep a single parameter
TestUtils.assertFileContains(apiFile.toPath(),
"_queryParams('', 'deepFilter', deepFilter)",
"_queryParams('', 'flatFilter', flatFilter)");
}

@Test(description = "Enum properties with defaults should emit enum constructor, not string literal")
public void testEnumDefaultUsesEnumConstructor() throws Exception {
List<File> files = generateDartNativeFromSpec(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
openapi: 3.0.3
info:
title: Exploded object query parameters
description: >
Object typed query parameters, covering the four combinations of style and explode that
decide how an object is put on the wire. The free-form variants matter because a
free-form object is flagged isMap but not isContainer.
version: 1.0.0
servers:
- url: localhost:8080
paths:
/items:
get:
operationId: listItems
parameters:
# style and explode both left out, so the form/true defaults apply: every entry
# becomes its own parameter, keyed by the property name alone.
- in: query
name: filter
schema:
type: object
# the same, but declared as a map rather than as a free-form object
- in: query
name: typedFilter
schema:
type: object
additionalProperties:
type: string
# deepObject nests each entry under the parameter name: deepFilter[key]=value
- in: query
name: deepFilter
style: deepObject
explode: true
schema:
type: object
# form without explode keeps a single parameter carrying the whole object
- in: query
name: flatFilter
style: form
explode: false
schema:
type: object
responses:
'200':
description: a list of items
content:
application/json:
schema:
type: array
items:
type: string
Original file line number Diff line number Diff line change
Expand Up @@ -1382,7 +1382,8 @@ class FakeApi {
queryParams.addAll(_queryParams('csv', 'url', url));
queryParams.addAll(_queryParams('multi', 'context', context));
if (language != null) {
queryParams.addAll(_queryParams('', 'language', language));
// form style explodes an object into one query parameter per entry, keyed by the property name alone
language.forEach((entryKey, entryValue) => queryParams.addAll(_queryParams('', entryKey.toString(), entryValue)));
}
queryParams.addAll(_queryParams('', 'allowEmpty', allowEmpty));

Expand Down