Skip to content

Commit

Permalink
[dart-dio] Incorrect hashCode and == overide for fields withList
Browse files Browse the repository at this point in the history
  • Loading branch information
vasilich6107 committed Apr 25, 2024
1 parent 1bfe800 commit 1da43e0
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 20 deletions.
1 change: 1 addition & 0 deletions docs/generators/dart-dio.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|<dl><dt>**false**</dt><dd>No changes to the enum's are made, this is the default option.</dd><dt>**true**</dt><dd>With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.</dd></dl>|false|
|equalityCheckMethod|Specify equality check method|<dl><dt>**default**</dt><dd>[DEFAULT] ...</dd><dt>**equatable**</dt><dd>....</dd></dl>|default|
|finalProperties|Whether properties are marked as final when using Json Serializable for serialization| |true|
|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C# have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8523,7 +8523,7 @@ protected void handleConstantParams(CodegenOperation operation) {
// Also, adds back non constant params to allParams.
for (CodegenParameter p : copy) {
if (p.isEnum && p.required && p._enum != null && p._enum.size() == 1) {
// Add to constantParams for use in the code generation templates.
// Add to constantParams for use in the code generation templates.
operation.constantParams.add(p);
if (p.isQueryParam) {
operation.queryParams.removeIf(param -> param.baseName.equals(p.baseName));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
public static final String DATE_LIBRARY_TIME_MACHINE = "timemachine";
public static final String DATE_LIBRARY_DEFAULT = DATE_LIBRARY_CORE;

public static final String EQUALITY_CHECK_METHOD = "equalityCheckMethod";
public static final String EQUALITY_CHECK_METHOD_DEFAULT = "default";
public static final String EQUALITY_CHECK_METHOD_EQUATABLE = "equatable";
public static final String SERIALIZATION_LIBRARY_BUILT_VALUE = "built_value";
public static final String SERIALIZATION_LIBRARY_JSON_SERIALIZABLE = "json_serializable";
public static final String SERIALIZATION_LIBRARY_DEFAULT = SERIALIZATION_LIBRARY_BUILT_VALUE;
Expand All @@ -71,6 +74,7 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
private static final String CLIENT_NAME = "clientName";

private String dateLibrary;
private String equalityCheckMethod;

private String clientName;

Expand Down Expand Up @@ -107,19 +111,30 @@ public DartDioClientCodegen() {
serializationLibrary.setDefault(SERIALIZATION_LIBRARY_DEFAULT);
cliOptions.add(serializationLibrary);

// Equality check option
final CliOption equalityCheckOption = CliOption.newString(EQUALITY_CHECK_METHOD, "Specify equality check method");
equalityCheckOption.setDefault(EQUALITY_CHECK_METHOD_DEFAULT);

final Map<String, String> equalityCheckOptions = new HashMap<>();
equalityCheckOptions.put(EQUALITY_CHECK_METHOD_DEFAULT, "[DEFAULT] ...");
equalityCheckOptions.put(EQUALITY_CHECK_METHOD_EQUATABLE, "....");
equalityCheckOption.setEnum(equalityCheckOptions);
cliOptions.add(equalityCheckOption);

// Date Library Option
final CliOption dateOption = CliOption.newString(DATE_LIBRARY, "Specify Date library");
dateOption.setDefault(DATE_LIBRARY_DEFAULT);

final CliOption finalProperties = CliOption.newBoolean(FINAL_PROPERTIES, "Whether properties are marked as final when using Json Serializable for serialization");
finalProperties.setDefault("true");
cliOptions.add(finalProperties);

final Map<String, String> dateOptions = new HashMap<>();
dateOptions.put(DATE_LIBRARY_CORE, "[DEFAULT] Dart core library (DateTime)");
dateOptions.put(DATE_LIBRARY_TIME_MACHINE, "Time Machine is date and time library for Flutter, Web, and Server with support for timezones, calendars, cultures, formatting and parsing.");
dateOption.setEnum(dateOptions);
cliOptions.add(dateOption);

// Final Properties Option
final CliOption finalProperties = CliOption.newBoolean(FINAL_PROPERTIES, "Whether properties are marked as final when using Json Serializable for serialization");
finalProperties.setDefault("true");
cliOptions.add(finalProperties);
}

public String getDateLibrary() {
Expand All @@ -130,6 +145,14 @@ public void setDateLibrary(String library) {
this.dateLibrary = library;
}

public String getEqualityCheckMethod() {
return equalityCheckMethod;
}

public void setEqualityCheckMethod(String equalityCheckMethod) {
this.equalityCheckMethod = equalityCheckMethod;
}

public String getClientName() {
return clientName;
}
Expand Down Expand Up @@ -172,6 +195,12 @@ public void processOpts() {
}
setDateLibrary(additionalProperties.get(DATE_LIBRARY).toString());

if (!additionalProperties.containsKey(EQUALITY_CHECK_METHOD)) {
additionalProperties.put(EQUALITY_CHECK_METHOD, EQUALITY_CHECK_METHOD_DEFAULT);
LOGGER.debug("Equality check method not set, using default {}", EQUALITY_CHECK_METHOD_DEFAULT);
}
setEqualityCheckMethod(additionalProperties.get(EQUALITY_CHECK_METHOD).toString());

if (!additionalProperties.containsKey(FINAL_PROPERTIES)) {
additionalProperties.put(FINAL_PROPERTIES, Boolean.parseBoolean(FINAL_PROPERTIES_DEFAULT_VALUE));
LOGGER.debug("finalProperties not set, using default {}", FINAL_PROPERTIES_DEFAULT_VALUE);
Expand Down Expand Up @@ -205,6 +234,7 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("auth/auth.mustache", authFolder, "auth.dart"));

configureSerializationLibrary(srcFolder);
configureEqualityCheckMethod(srcFolder);
configureDateLibrary(srcFolder);
}

Expand Down Expand Up @@ -278,6 +308,17 @@ private void configureSerializationLibraryJsonSerializable(String srcFolder) {
imports.put("MultipartFile", DIO_IMPORT);
}

private void configureEqualityCheckMethod(String srcFolder) {
switch (equalityCheckMethod) {
case EQUALITY_CHECK_METHOD_EQUATABLE:
additionalProperties.put("useEquatable", "true");
break;
default:
case EQUALITY_CHECK_METHOD_DEFAULT:
break;
}
}

private void configureDateLibrary(String srcFolder) {
switch (dateLibrary) {
case DATE_LIBRARY_TIME_MACHINE:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ dependencies:
built_value: '>=8.4.0 <9.0.0'
built_collection: '>=5.1.1 <6.0.0'
{{/useBuiltValue}}
{{#useEquatable}}
equatable: '^2.0.5'
{{/useEquatable}}
{{#useJsonSerializable}}
json_annotation: '^4.4.0'
{{/useJsonSerializable}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import 'package:json_annotation/json_annotation.dart';
{{#useEquatable}}
import 'package:equatable/src/equatable_utils.dart';
{{/useEquatable}}

part '{{classFilename}}.g.dart';

Expand Down Expand Up @@ -61,17 +64,50 @@ class {{{classname}}} {


{{/vars}}
@override
bool operator ==(Object other) => identical(this, other) || other is {{{classname}}} &&
{{#vars}}
other.{{{name}}} == {{{name}}}{{^-last}} &&{{/-last}}{{#-last}};{{/-last}}
{{/vars}}

@override
int get hashCode =>
{{#vars}}
{{#isNullable}}({{{name}}} == null ? 0 : {{{name}}}.hashCode){{/isNullable}}{{^isNullable}}{{{name}}}.hashCode{{/isNullable}}{{^-last}} +{{/-last}}{{#-last}};{{/-last}}
{{/vars}}
{{#useEquatable}}
bool operator ==(Object other) {
return identical(this, other) ||
other is {{{classname}}} &&
runtimeType == other.runtimeType &&
equals(
[
{{#vars}}
{{{name}}},
{{/vars}}
],
[
{{#vars}}
other.{{{name}}},
{{/vars}}
]
);
}
{{/useEquatable}}

{{^useEquatable}}
@override
bool operator ==(Object other) => identical(this, other) || other is {{{classname}}} &&
{{#vars}}
other.{{{name}}} == {{{name}}}{{^-last}} &&{{/-last}}{{#-last}};{{/-last}}
{{/vars}}
{{/useEquatable}}

{{#useEquatable}}
@override
int get hashCode => runtimeType.hashCode ^ mapPropsToHashCode([
{{#vars}}
{{{name}}},
{{/vars}}
],);
{{/useEquatable}}
{{^useEquatable}}
@override
int get hashCode =>
{{#vars}}
{{#isNullable}}({{{name}}} == null ? 0 : {{{name}}}.hashCode){{/isNullable}}{{^isNullable}}{{{name}}}.hashCode{{/isNullable}}{{^-last}} +{{/-last}}{{#-last}};{{/-last}}
{{/vars}}
{{/useEquatable}}

factory {{{classname}}}.fromJson(Map<String, dynamic> json) => _${{{classname}}}FromJson(json);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import 'package:json_annotation/json_annotation.dart';
enum {{{classname}}} {
{{#allowableValues}}
{{#enumVars}}
{{#description}}
/// {{{.}}}
{{/description}}
@JsonValue({{#isString}}r{{/isString}}{{{value}}})
{{{name}}}({{^isString}}'{{/isString}}{{#isString}}r{{/isString}}{{{value}}}{{^isString}}'{{/isString}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
{{^isNull}}
{{#description}}
/// {{{.}}}
{{/description}}
@JsonValue({{#isString}}r{{/isString}}{{{value}}})
{{{name}}}({{^isString}}'{{/isString}}{{#isString}}r{{/isString}}{{{value}}}{{^isString}}'{{/isString}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
{{/isNull}}
{{/enumVars}}
{{/allowableValues}}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.openapitools.codegen.AbstractOptionsTest;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.languages.DartClientCodegen;
import org.openapitools.codegen.languages.DartDioClientCodegen;
import org.openapitools.codegen.options.DartClientOptionsProvider;

import static org.mockito.Mockito.mock;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ protected void verifyOptions() {
verify(clientCodegen).setUseEnumExtension(Boolean.parseBoolean(DartDioClientOptionsProvider.USE_ENUM_EXTENSION));
verify(clientCodegen).setDateLibrary(DartDioClientCodegen.DATE_LIBRARY_DEFAULT);
verify(clientCodegen).setLibrary(DartDioClientCodegen.SERIALIZATION_LIBRARY_DEFAULT);
verify(clientCodegen).setEqualityCheckMethod(DartDioClientCodegen.EQUALITY_CHECK_METHOD_DEFAULT);
verify(clientCodegen).setEnumUnknownDefaultCase(Boolean.parseBoolean(DartDioClientOptionsProvider.ENUM_UNKNOWN_DEFAULT_CASE_VALUE));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public Map<String, String> createOptions() {
.put(CodegenConstants.SERIALIZATION_LIBRARY, DartDioClientCodegen.SERIALIZATION_LIBRARY_DEFAULT)
.put(DartDioClientCodegen.DATE_LIBRARY, DartDioClientCodegen.DATE_LIBRARY_DEFAULT)
.put(DartDioClientCodegen.FINAL_PROPERTIES, DartDioClientCodegen.FINAL_PROPERTIES_DEFAULT_VALUE)
.put(DartDioClientCodegen.EQUALITY_CHECK_METHOD, DartDioClientCodegen.EQUALITY_CHECK_METHOD_DEFAULT)
.put(CodegenConstants.SOURCE_FOLDER, SOURCE_FOLDER_VALUE)
.put(DartDioClientCodegen.USE_ENUM_EXTENSION, USE_ENUM_EXTENSION)
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
Expand Down

0 comments on commit 1da43e0

Please sign in to comment.