Browse Source

feat(dynamite): Override equality operators

Signed-off-by: jld3103 <jld3103yt@gmail.com>
pull/715/head
jld3103 1 year ago
parent
commit
aa9a24be0e
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 10
      packages/dynamite/dynamite/lib/src/models/components.dart
  2. 10
      packages/dynamite/dynamite/lib/src/models/discriminator.dart
  3. 7
      packages/dynamite/dynamite/lib/src/models/header.dart
  4. 8
      packages/dynamite/dynamite/lib/src/models/info.dart
  5. 7
      packages/dynamite/dynamite/lib/src/models/license.dart
  6. 6
      packages/dynamite/dynamite/lib/src/models/media_type.dart
  7. 26
      packages/dynamite/dynamite/lib/src/models/open_api.dart
  8. 30
      packages/dynamite/dynamite/lib/src/models/operation.dart
  9. 12
      packages/dynamite/dynamite/lib/src/models/parameter.dart
  10. 27
      packages/dynamite/dynamite/lib/src/models/path_item.dart
  11. 3
      packages/dynamite/dynamite/lib/src/models/paths.dart
  12. 9
      packages/dynamite/dynamite/lib/src/models/request_body.dart
  13. 11
      packages/dynamite/dynamite/lib/src/models/response.dart
  14. 3
      packages/dynamite/dynamite/lib/src/models/responses.dart
  15. 49
      packages/dynamite/dynamite/lib/src/models/schema.dart
  16. 1
      packages/dynamite/dynamite/lib/src/models/security_requirement.dart
  17. 9
      packages/dynamite/dynamite/lib/src/models/security_scheme.dart
  18. 8
      packages/dynamite/dynamite/lib/src/models/server.dart
  19. 9
      packages/dynamite/dynamite/lib/src/models/server_variable.dart
  20. 7
      packages/dynamite/dynamite/lib/src/models/tag.dart
  21. 244
      packages/dynamite/dynamite/test/equality_test.dart

10
packages/dynamite/dynamite/lib/src/models/components.dart

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:dynamite/src/models/schema.dart';
import 'package:dynamite/src/models/security_scheme.dart';
import 'package:json_annotation/json_annotation.dart';
@ -19,4 +20,13 @@ class Components {
final Map<String, SecurityScheme>? securitySchemes;
final Map<String, Schema>? schemas;
@override
bool operator ==(final Object other) =>
other is Components &&
const MapEquality().equals(securitySchemes, other.securitySchemes) &&
const MapEquality().equals(schemas, other.schemas);
@override
int get hashCode => const MapEquality().hash(securitySchemes) + const MapEquality().hash(schemas);
}

10
packages/dynamite/dynamite/lib/src/models/discriminator.dart

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';
@ -17,4 +18,13 @@ class Discriminator {
final String propertyName;
final Map<String, String>? mapping;
@override
bool operator ==(final Object other) =>
other is Discriminator &&
propertyName == other.propertyName &&
const MapEquality().equals(mapping, other.mapping);
@override
int get hashCode => propertyName.hashCode + const MapEquality().hash(mapping);
}

7
packages/dynamite/dynamite/lib/src/models/header.dart

@ -16,9 +16,16 @@ class Header {
factory Header.fromJson(final Map<String, dynamic> json) => _$HeaderFromJson(json);
Map<String, dynamic> toJson() => _$HeaderToJson(this);
// Ignored in the comparison as it doesn't affect the generated code
final String? description;
final bool? required;
final Schema? schema;
@override
bool operator ==(final Object other) => other is Header && required == other.required && schema == other.schema;
@override
int get hashCode => Object.hashAll([required, schema]);
}

8
packages/dynamite/dynamite/lib/src/models/info.dart

@ -17,11 +17,19 @@ class Info {
factory Info.fromJson(final Map<String, dynamic> json) => _$InfoFromJson(json);
Map<String, dynamic> toJson() => _$InfoToJson(this);
// Ignored in the comparison as it doesn't affect the generated code
final String title;
final String version;
final License license;
// Ignored in the comparison as it doesn't affect the generated code
final String? description;
@override
bool operator ==(final Object other) => other is Info && version == other.version && license == other.license;
@override
int get hashCode => version.hashCode + license.hashCode;
}

7
packages/dynamite/dynamite/lib/src/models/license.dart

@ -20,4 +20,11 @@ class License {
final String? identifier;
final String? url;
@override
bool operator ==(final Object other) =>
other is License && name == other.name && identifier == other.identifier && url == other.url;
@override
int get hashCode => name.hashCode + identifier.hashCode + url.hashCode;
}

6
packages/dynamite/dynamite/lib/src/models/media_type.dart

@ -15,4 +15,10 @@ class MediaType {
Map<String, dynamic> toJson() => _$MediaTypeToJson(this);
final Schema? schema;
@override
bool operator ==(final Object other) => other is MediaType && schema == other.schema;
@override
int get hashCode => schema.hashCode;
}

26
packages/dynamite/dynamite/lib/src/models/open_api.dart

@ -1,8 +1,7 @@
import 'package:collection/collection.dart';
import 'package:dynamite/src/models/components.dart';
import 'package:dynamite/src/models/info.dart';
import 'package:dynamite/src/models/path_item.dart';
import 'package:dynamite/src/models/paths.dart';
import 'package:dynamite/src/models/security_requirement.dart';
import 'package:dynamite/src/models/server.dart';
import 'package:dynamite/src/models/tag.dart';
import 'package:json_annotation/json_annotation.dart';
@ -33,13 +32,13 @@ class OpenAPI {
final List<Server>? servers;
final List<SecurityRequirement>? security;
final List<Map<String, List<String>>>? security;
final List<Tag>? tags;
final Components? components;
final Paths? paths;
final Map<String, PathItem>? paths;
bool get hasAnySecurity => components?.securitySchemes?.isNotEmpty ?? false;
@ -50,4 +49,23 @@ class OpenAPI {
yield* matchedTags.single.formattedDescription;
}
}
@override
bool operator ==(final Object other) =>
other is OpenAPI &&
info == other.info &&
const ListEquality().equals(servers, other.servers) &&
const DeepCollectionEquality().equals(security, other.security) &&
const ListEquality().equals(tags, other.tags) &&
components == other.components &&
const MapEquality().equals(paths, other.paths);
@override
int get hashCode =>
info.hashCode +
const ListEquality().hash(servers) +
const DeepCollectionEquality().hash(security) +
const ListEquality().hash(tags) +
components.hashCode +
const MapEquality().hash(paths);
}

30
packages/dynamite/dynamite/lib/src/models/operation.dart

@ -1,9 +1,8 @@
import 'package:collection/collection.dart';
import 'package:dynamite/src/helpers/docs.dart';
import 'package:dynamite/src/models/parameter.dart';
import 'package:dynamite/src/models/request_body.dart';
import 'package:dynamite/src/models/response.dart';
import 'package:dynamite/src/models/responses.dart';
import 'package:dynamite/src/models/security_requirement.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';
@ -29,8 +28,10 @@ class Operation {
final String? operationId;
// Ignored in the comparison as it doesn't affect the generated code
final String? summary;
// Ignored in the comparison as it doesn't affect the generated code
final String? description;
final bool? deprecated;
@ -41,9 +42,9 @@ class Operation {
final RequestBody? requestBody;
final Responses? responses;
final Map<String, Response>? responses;
final List<SecurityRequirement>? security;
final List<Map<String, List<String>>>? security;
Iterable<String> get formattedDescription sync* {
yield* descriptionToDocs(summary);
@ -54,4 +55,25 @@ class Operation {
yield* descriptionToDocs(description);
}
@override
bool operator ==(final Object other) =>
other is Operation &&
operationId == other.operationId &&
deprecated == other.deprecated &&
const ListEquality().equals(tags, other.tags) &&
const ListEquality().equals(parameters, other.parameters) &&
requestBody == other.requestBody &&
const MapEquality().equals(responses, other.responses) &&
const DeepCollectionEquality().equals(security, other.security);
@override
int get hashCode =>
operationId.hashCode +
deprecated.hashCode +
const ListEquality().hash(tags) +
const ListEquality().hash(parameters) +
requestBody.hashCode +
const MapEquality().hash(responses) +
const DeepCollectionEquality().hash(security);
}

12
packages/dynamite/dynamite/lib/src/models/parameter.dart

@ -24,6 +24,7 @@ class Parameter {
@JsonKey(name: 'in')
final String in_;
// Ignored in the comparison as it doesn't affect the generated code
final String? description;
final bool? required;
@ -31,4 +32,15 @@ class Parameter {
final Schema? schema;
bool get isDartRequired => isRequired(required, schema?.default_);
@override
bool operator ==(final Object other) =>
other is Parameter &&
name == other.name &&
in_ == other.in_ &&
required == other.required &&
schema == other.schema;
@override
int get hashCode => name.hashCode + in_.hashCode + required.hashCode + schema.hashCode;
}

27
packages/dynamite/dynamite/lib/src/models/path_item.dart

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:dynamite/src/models/operation.dart';
import 'package:dynamite/src/models/parameter.dart';
import 'package:json_annotation/json_annotation.dart';
@ -24,6 +25,7 @@ class PathItem {
factory PathItem.fromJson(final Map<String, dynamic> json) => _$PathItemFromJson(json);
Map<String, dynamic> toJson() => _$PathItemToJson(this);
// Ignored in the comparison as it doesn't affect the generated code
final String? description;
final List<Parameter>? parameters;
@ -67,4 +69,29 @@ class PathItem {
patch: operations['patch'] ?? patch,
trace: operations['trace'] ?? trace,
);
@override
bool operator ==(final Object other) =>
other is PathItem &&
const ListEquality().equals(parameters, other.parameters) &&
get == other.get &&
put == other.put &&
post == other.post &&
delete == other.delete &&
options == other.options &&
head == other.head &&
patch == other.patch &&
trace == other.trace;
@override
int get hashCode =>
const ListEquality().hash(parameters) +
get.hashCode +
put.hashCode +
post.hashCode +
delete.hashCode +
options.hashCode +
head.hashCode +
patch.hashCode +
trace.hashCode;
}

3
packages/dynamite/dynamite/lib/src/models/paths.dart

@ -1,3 +0,0 @@
import 'package:dynamite/src/models/path_item.dart';
typedef Paths = Map<String, PathItem>;

9
packages/dynamite/dynamite/lib/src/models/request_body.dart

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:dynamite/src/models/media_type.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';
@ -16,9 +17,17 @@ class RequestBody {
factory RequestBody.fromJson(final Map<String, dynamic> json) => _$RequestBodyFromJson(json);
Map<String, dynamic> toJson() => _$RequestBodyToJson(this);
// Ignored in the comparison as it doesn't affect the generated code
final String? description;
final Map<String, MediaType>? content;
final bool? required;
@override
bool operator ==(final Object other) =>
other is RequestBody && const MapEquality().equals(content, other.content) && required == other.required;
@override
int get hashCode => const MapEquality().hash(content) + required.hashCode;
}

11
packages/dynamite/dynamite/lib/src/models/response.dart

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:dynamite/src/models/header.dart';
import 'package:dynamite/src/models/media_type.dart';
import 'package:json_annotation/json_annotation.dart';
@ -17,9 +18,19 @@ class Response {
factory Response.fromJson(final Map<String, dynamic> json) => _$ResponseFromJson(json);
Map<String, dynamic> toJson() => _$ResponseToJson(this);
// Ignored in the comparison as it doesn't affect the generated code
final String description;
final Map<String, MediaType>? content;
final Map<String, Header>? headers;
@override
bool operator ==(final Object other) =>
other is Response &&
const MapEquality().equals(content, other.content) &&
const MapEquality().equals(headers, other.headers);
@override
int get hashCode => const MapEquality().hash(content) + const MapEquality().hash(headers);
}

3
packages/dynamite/dynamite/lib/src/models/responses.dart

@ -1,3 +0,0 @@
import 'package:dynamite/src/models/response.dart';
typedef Responses = Map<String, Response>;

49
packages/dynamite/dynamite/lib/src/models/schema.dart

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:dynamite/src/helpers/docs.dart';
import 'package:dynamite/src/models/discriminator.dart';
import 'package:json_annotation/json_annotation.dart';
@ -46,6 +47,7 @@ class Schema {
List<Schema>? get ofs => oneOf ?? anyOf ?? allOf;
// Ignored in the comparison as it doesn't affect the generated code
final String? description;
final bool? deprecated;
@ -88,6 +90,53 @@ class Schema {
bool get isContentString => type == 'string' && (contentMediaType?.isNotEmpty ?? false) && contentSchema != null;
Iterable<String> get formattedDescription => descriptionToDocs(description);
@override
bool operator ==(final Object other) =>
other is Schema &&
ref == other.ref &&
const ListEquality().equals(oneOf, other.oneOf) &&
const ListEquality().equals(anyOf, other.anyOf) &&
const ListEquality().equals(allOf, other.allOf) &&
deprecated == other.deprecated &&
type == other.type &&
format == other.format &&
default_ == other.default_ &&
const ListEquality().equals(enum_, other.enum_) &&
const MapEquality().equals(properties, other.properties) &&
const ListEquality().equals(required, other.required) &&
items == other.items &&
additionalProperties == other.additionalProperties &&
contentMediaType == other.contentMediaType &&
contentSchema == other.contentSchema &&
discriminator == other.discriminator &&
pattern == other.pattern &&
minLength == other.minLength &&
maxLength == other.maxLength &&
nullable == other.nullable;
@override
int get hashCode =>
ref.hashCode +
const ListEquality().hash(oneOf) +
const ListEquality().hash(anyOf) +
const ListEquality().hash(allOf) +
deprecated.hashCode +
type.hashCode +
format.hashCode +
default_.hashCode +
const ListEquality().hash(enum_) +
const MapEquality().hash(properties) +
const ListEquality().hash(required) +
items.hashCode +
additionalProperties.hashCode +
contentMediaType.hashCode +
contentSchema.hashCode +
discriminator.hashCode +
pattern.hashCode +
minLength.hashCode +
maxLength.hashCode +
nullable.hashCode;
}
class EmptySchema extends Schema {

1
packages/dynamite/dynamite/lib/src/models/security_requirement.dart

@ -1 +0,0 @@
typedef SecurityRequirement = Map<String, List<String>>;

9
packages/dynamite/dynamite/lib/src/models/security_scheme.dart

@ -16,6 +16,15 @@ class SecurityScheme {
Map<String, dynamic> toJson() => _$SecuritySchemeToJson(this);
final String type;
// Ignored in the comparison as it doesn't affect the generated code
final String? description;
final String? scheme;
@override
bool operator ==(final Object other) => other is SecurityScheme && type == other.type && scheme == other.scheme;
@override
int get hashCode => type.hashCode + scheme.hashCode;
}

8
packages/dynamite/dynamite/lib/src/models/server.dart

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:dynamite/src/models/server_variable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';
@ -18,4 +19,11 @@ class Server {
final String url;
final Map<String, ServerVariable>? variables;
@override
bool operator ==(final Object other) =>
other is Server && url == other.url && const MapEquality().equals(variables, other.variables);
@override
int get hashCode => url.hashCode + const MapEquality().hash(variables);
}

9
packages/dynamite/dynamite/lib/src/models/server_variable.dart

@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';
@ -21,5 +22,13 @@ class ServerVariable {
@JsonKey(name: 'enum')
final List<String>? enum_;
// Ignored in the comparison as it doesn't affect the generated code
final String? description;
@override
bool operator ==(final Object other) =>
other is ServerVariable && default_ == other.default_ && const ListEquality().equals(enum_, other.enum_);
@override
int get hashCode => default_.hashCode + const ListEquality().hash(enum_);
}

7
packages/dynamite/dynamite/lib/src/models/tag.dart

@ -17,7 +17,14 @@ class Tag {
final String name;
// Ignored in the comparison as it doesn't affect the generated code
final String? description;
Iterable<String> get formattedDescription => descriptionToDocs(description);
@override
bool operator ==(final Object other) => other is Tag && name == other.name;
@override
int get hashCode => name.hashCode;
}

244
packages/dynamite/dynamite/test/equality_test.dart

@ -0,0 +1,244 @@
// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables
import 'dart:math';
import 'package:dynamite/src/models/components.dart';
import 'package:dynamite/src/models/discriminator.dart';
import 'package:dynamite/src/models/header.dart';
import 'package:dynamite/src/models/info.dart';
import 'package:dynamite/src/models/license.dart';
import 'package:dynamite/src/models/media_type.dart';
import 'package:dynamite/src/models/open_api.dart';
import 'package:dynamite/src/models/operation.dart';
import 'package:dynamite/src/models/parameter.dart';
import 'package:dynamite/src/models/path_item.dart';
import 'package:dynamite/src/models/request_body.dart';
import 'package:dynamite/src/models/response.dart';
import 'package:dynamite/src/models/schema.dart';
import 'package:dynamite/src/models/security_scheme.dart';
import 'package:dynamite/src/models/server.dart';
import 'package:dynamite/src/models/server_variable.dart';
import 'package:dynamite/src/models/tag.dart';
import 'package:test/expect.dart';
import 'package:test/scaffolding.dart';
Components getComponents() => Components(
securitySchemes: {'': getSecurityScheme()},
schemas: {'': getSchema()},
);
Discriminator getDiscriminator() => Discriminator(
propertyName: '',
mapping: {'': ''},
);
Header getHeader() => Header(
description: getRandomString(),
required: true,
schema: getSchema(),
);
Info getInfo() => Info(
title: getRandomString(),
version: '',
license: getLicense(),
description: getRandomString(),
);
License getLicense() => License(
name: '',
identifier: '',
url: '',
);
MediaType getMediaType() => MediaType(
schema: getSchema(),
);
OpenAPI getOpenAPI() => OpenAPI(
version: '',
info: getInfo(),
servers: [getServer()],
security: [
{
'': [''],
}
],
tags: [getTag()],
components: getComponents(),
paths: {'': getPathItem()},
);
Operation getOperation() => Operation(
operationId: '',
summary: getRandomString(),
description: getRandomString(),
deprecated: true,
tags: [''],
parameters: [getParameter()],
requestBody: getRequestBody(),
responses: {'': getResponse()},
security: [
{
'': [''],
}
],
);
Parameter getParameter() => Parameter(
name: '',
in_: '',
description: getRandomString(),
required: true,
schema: getSchema(),
);
PathItem getPathItem() => PathItem(
description: getRandomString(),
parameters: [getParameter()],
get: getOperation(),
put: getOperation(),
post: getOperation(),
delete: getOperation(),
options: getOperation(),
head: getOperation(),
patch: getOperation(),
trace: getOperation(),
);
RequestBody getRequestBody() => RequestBody(
description: getRandomString(),
content: {'': getMediaType()},
required: true,
);
Response getResponse() => Response(
description: getRandomString(),
content: {'': getMediaType()},
headers: {'': getHeader()},
);
Schema getSchema() => Schema(
ref: '',
oneOf: [Schema()],
anyOf: [Schema()],
allOf: [Schema()],
description: getRandomString(),
deprecated: true,
type: '',
format: '',
default_: '',
enum_: [''],
properties: {'': Schema()},
required: [''],
items: Schema(),
additionalProperties: Schema(),
contentMediaType: '',
contentSchema: Schema(),
discriminator: getDiscriminator(),
pattern: '',
minLength: 0,
maxLength: 0,
nullable: true,
);
SecurityScheme getSecurityScheme() => SecurityScheme(
type: '',
description: getRandomString(),
scheme: '',
);
Server getServer() => Server(
url: '',
variables: {'': getServerVariable()},
);
ServerVariable getServerVariable() => ServerVariable(
default_: '',
enum_: [''],
description: getRandomString(),
);
Tag getTag() => Tag(
name: '',
description: getRandomString(),
);
void expectSame(final dynamic a, final dynamic b) {
expect(a, equals(b));
expect(a.hashCode, equals(b.hashCode));
}
String getRandomString() {
final r = Random();
return String.fromCharCodes(List.generate(16, (final index) => r.nextInt(33) + 89));
}
void main() {
test('Components', () {
expectSame(getComponents(), getComponents());
});
test('Discriminator', () {
expectSame(getDiscriminator(), getDiscriminator());
});
test('Header', () {
expectSame(getHeader(), getHeader());
});
test('Info', () {
expectSame(getInfo(), getInfo());
});
test('License', () {
expectSame(getLicense(), getLicense());
});
test('MediaType', () {
expectSame(getMediaType(), getMediaType());
});
test('OpenAPI', () {
expectSame(getOpenAPI(), getOpenAPI());
});
test('Operation', () {
expectSame(getOperation(), getOperation());
});
test('Parameter', () {
expectSame(getParameter(), getParameter());
});
test('PathItem', () {
expectSame(getPathItem(), getPathItem());
});
test('RequestBody', () {
expectSame(getRequestBody(), getRequestBody());
});
test('Response', () {
expectSame(getResponse(), getResponse());
});
test('Schema', () {
expectSame(getSchema(), getSchema());
});
test('SecurityScheme', () {
expectSame(getSecurityScheme(), getSecurityScheme());
});
test('Server', () {
expectSame(getServer(), getServer());
});
test('ServerVariable', () {
expectSame(getServerVariable(), getServerVariable());
});
test('Tag', () {
expectSame(getTag(), getTag());
});
}
Loading…
Cancel
Save