Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V8 #97

Merged
merged 19 commits into from
Jan 23, 2024
Merged

V8 #97

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f6a3b1e
initial cut of version 8
rvowles Sep 23, 2023
9f66ac3
passing all existing tests now
rvowles Sep 23, 2023
8a63f16
fix for array copies and enhancing changelog for migration.
rvowles Sep 23, 2023
c7a6123
add model and api deprecation drop support
rvowles Oct 7, 2023
55ef022
swap to an RC
rvowles Oct 8, 2023
7b8fae8
[maven-release-plugin] prepare release openapi-dart-generator-8.1-RC1
rvowles Oct 8, 2023
f52fcd5
[maven-release-plugin] prepare for next development iteration
rvowles Oct 8, 2023
ecab68f
increase minimum version of opendart_dart_common
rvowles Oct 8, 2023
85c32bb
fix issue where arrays/maps with no defaults were still getting them
rvowles Oct 14, 2023
683b493
fix issue with non-nullable arrays and late init
rvowles Oct 14, 2023
ae29961
[maven-release-plugin] prepare release openapi-dart-generator-8.1-RC2
rvowles Oct 14, 2023
7bc3eb5
[maven-release-plugin] prepare for next development iteration
rvowles Oct 14, 2023
317eb8e
fix issue with required fields
rvowles Oct 15, 2023
4e5f5ee
goosed up the array handling and central half-baked the release
rvowles Oct 15, 2023
23e8bf5
[maven-release-plugin] prepare release openapi-dart-generator-8.1-RC4
rvowles Oct 15, 2023
80e3b83
[maven-release-plugin] prepare for next development iteration
rvowles Oct 15, 2023
daa71a5
8.1 ready for use
rvowles Jan 23, 2024
72863b0
[maven-release-plugin] prepare release openapi-dart-generator-8.1
rvowles Jan 23, 2024
cab822b
[maven-release-plugin] prepare for next development iteration
rvowles Jan 23, 2024
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
31 changes: 31 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
= Changelog

== 8.x Series is based on OpenAPI 7.x+

- The OpenAPI base now shifts to version 7 and Java 11.
- It also shifts to a more strict interpretation of nullable (a field can have a null value) vs required (a field
is required, but can be null or non null). A field is REQUIRED is it is marked as required, or if it is *not nullable*
and has no default (otherwise Dart doesn't know what to do with it).
- We drop support for pre-Dart 2.12 code (i.e. non-null safe code)
- We add the ability to drop deprecated APIs (additional property `filter-deprecated-apis`)
- We add the ability to drop deprecated Models (additional property `filter-deprecated-models`)


If you want to support something like Person? then you need something like this:

----
SomeClass:
properties:
person: # do not include a description or the API changes code generation
nullable: true
allOf:
- $ref: "#/components/schemas/Person"
----

This text snippet does not change the API, you get a `Person? person` field. If you add a description,
OpenAPI will automatically generate a new class which is outside of our control, and you will get a new
class likely called `SomeClassPerson` so it can hold the description.

If you put `nullable: true` on the definition of the object itself, it inherently turns the object to
always be nullable, so you get things like `List<Person?> people`.



== 7.x Series is based on OpenAPI 6.2+

The OpenAPI crew broke the API in weird ways in 6.2, so we go to a new major
Expand Down
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
This plugin was originally designed for use by the OpenAPi v3 Maven Plugin, but works with the
command line generator and the Gradle plugin. it generates _excellent_ Dart code and uses Dio.

NOTE: we are currently using 6.4.0 of the OpenAPI Maven Plugin.
NOTE: we are currently using 7.0.1 of the OpenAPI Maven Plugin.

== Sponsors

Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
<artifactId>openapi-dart-generator</artifactId>
<packaging>jar</packaging>
<name>openapi-dart-generator</name>
<version>7.3-SNAPSHOT</version>
<version>8.2-SNAPSHOT</version>

<description>
dart2 generator from openapi 3.x spec files. Changing to openapitools dependencies.
dart2 generator from openapi 3.x spec files.
</description>

<url>https://www.bluetrainsoftware.com</url>
Expand All @@ -34,14 +34,14 @@
</scm>

<properties>
<openapi-codegen-version>6.4.0</openapi-codegen-version>
<openapi-codegen-version>7.0.1</openapi-codegen-version>
<maven.compiler.target>1.11</maven.compiler.target>
<maven.compiler.source>1.11</maven.compiler.source>
<kotlin.version>1.8.10</kotlin.version>
</properties>

<prerequisites>
<maven>3.5</maven>
<maven>3.8</maven>
</prerequisites>

<dependencies>
Expand Down
65 changes: 38 additions & 27 deletions sample-app/SampleRunner/test/api_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ main() {
print(w);
print(x);
print("codes ${w.hashCode} vs ${x.hashCode}");
expect(true, w.hashCode > 0, reason: '${w.hashCode} should be > 0');
print("empty array -> ${[].hashCode}");
expect(true, w.hashCode == x.hashCode);
expect(true, w.hashCode == x.hashCode,
reason:
'w hashcode: ${w.hashCode} should equal x hashcode: ${x.hashCode}');
var z = w.copyWith(types: [GeocodedWaypointTypesEnum.ADDRESS]);
expect(false, w == z);
expect(false, w.hashCode == z.hashCode);
Expand Down Expand Up @@ -54,19 +57,16 @@ main() {
test(
'hashing an object which has two fields of the same type is still different',
() {
var ht = HashTest()
..fieldOne = false
..fieldTwo = true;
var ht1 = HashTest()
..fieldOne = true
..fieldTwo = false;
var ht = HashTest(fieldOne: false, fieldTwo: true);
var ht1 = HashTest(fieldTwo: false, fieldOne: true);
expect(false, ht.hashCode == ht1.hashCode);
});

test('additional properties mappings', () {
const addProp = {
'discrim': 'fred',
'readings': {'one': 1, 'two': 2.3},
'extra': {},
'dependencies': {
'deps1': ['a', 34.2, true],
'deps2': [17.8, false, 'b']
Expand Down Expand Up @@ -97,24 +97,24 @@ main() {

var ap = AddProps3.fromJson(addProp);
expect(ap.discrim, 'fred');
expect(ap.readings.length, 2);
expect(ap.readings['one'], 1);
expect(ap.readings['two'], 2.3);
expect(ap.dependencies['deps1'], ['a', 34.2, true]);
expect(ap.dependencies['deps2'], [17.8, false, 'b']);
expect(ap.otherDeps['name'], ['tom', 'dick', 'harry']);
expect(ap.otherDeps['height'], [1.7, 1.3, 1.4]);
expect(ap.otherDeps['info'], 'this is top secret');
expect(ap.yetMoreAdditional['sList'], ['a', 'b', 'c']);
expect(ap.readings!.length, 2);
expect(ap.readings!['one'], 1);
expect(ap.readings!['two'], 2.3);
expect(ap.dependencies!['deps1'], ['a', 34.2, true]);
expect(ap.dependencies!['deps2'], [17.8, false, 'b']);
expect(ap.otherDeps!['name'], ['tom', 'dick', 'harry']);
expect(ap.otherDeps!['height'], [1.7, 1.3, 1.4]);
expect(ap.otherDeps!['info'], 'this is top secret');
expect(ap.yetMoreAdditional!['sList'], ['a', 'b', 'c']);
expect(
ap.mapWithComplexObject['c1']?[0],
Event()
..status = EventStatus.STREAMING
..id = 'xx'
..title = 'Scully'
..img = 'img'
..imageUrl = 'http://blah');
expect(ap.mapWithEnums['statuses'],
ap.mapWithComplexObject!['c1']?[0],
Event(
status: EventStatus.STREAMING,
id: 'xx',
title: 'Scully',
img: 'img',
imageUrl: 'http://blah'));
expect(ap.mapWithEnums!['statuses'],
[EventStatus.STREAMING, EventStatus.CLOSED]);
});

Expand All @@ -136,6 +136,7 @@ main() {
'basicInt': 2.6,
'basicDouble': 1,
'intList': [1, 2.6],
'int64Int': 33,
'intMap': {'one': 1, 'two': 2.7},
'doubleList': [1, 2.6],
'doubleMap': {'one': 1, 'two': 2.7},
Expand All @@ -145,16 +146,26 @@ main() {
expect(data.basicDouble, 1.0);
expect(data.basicInt, 2);
expect(data.intList, [1, 2]);
expect(data.int64Int, 33);
expect(data.intMap, {'one': 1, 'two': 2});
expect(data.doubleList, [1.0, 2.6]);
expect(data.doubleMap, {'one': 1.0, 'two': 2.7});
});
test('data serialisation', () {
final data = DoubleAndIntConversion(
basicInt: 43, basicDouble: 26.2, intList: [], doubleMap: {});
int64Int: 0,
intMap: {},
basicInt: 43,
basicDouble: 26.2,
intList: [],
doubleMap: {});
expect(data.toJson(), {
'basicInt': 43, 'basicDouble': 26.2, 'intList': [],
'doubleList': [], // because we can't tell between null and empty
'basicInt': 43,
'int64Int': 0,
'basicDouble': 26.2,
'intList': [],
'intMap': {},
'doubleList': [], // because it is not nullable
'doubleMap': {}
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/it/k8s_null/lib/int_or_string.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class IntOrString {
return IntOrString()..value = this.value;
}

dynamic? toJson() {
dynamic toJson() {
return this.value;
}

Expand Down
2 changes: 1 addition & 1 deletion src/it/k8s_null/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>6.4.0</version>
<version>7.0.1</version>
<dependencies>
<dependency>
<groupId>com.bluetrainsoftware.maven</groupId>
Expand Down
2 changes: 2 additions & 0 deletions src/it/k8s_null/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ components:
int64Int:
type: integer
format: int64
default: 0
basicDouble:
type: number
format: double
Expand All @@ -390,6 +391,7 @@ components:
type: integer
doubleList:
type: array
default: []
items:
type: number
format: double
Expand Down
86 changes: 51 additions & 35 deletions src/it/k8s_null/test/api_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ main() {
print(w);
print(x);
print("codes ${w.hashCode} vs ${x.hashCode}");
expect(true, w.hashCode > 0, reason: '${w.hashCode} should be > 0');
print("empty array -> ${[].hashCode}");
expect(true, w.hashCode == x.hashCode);
expect(true, w.hashCode == x.hashCode, reason: 'w hashcode: ${w.hashCode} should equal x hashcode: ${x.hashCode}');
var z = w.copyWith(types: [GeocodedWaypointTypesEnum.ADDRESS]);
expect(false, w == z);
expect(false, w.hashCode == z.hashCode);
Expand All @@ -33,20 +34,37 @@ main() {
expect(encodeDecode, w);
});

test('basic inheritance', () {
final wld = WithListDerived.fromJson({
"list": [
{"id": 1, "name": "one"},
{"id": 2, "name": "two"}
],
"id": 7,
"name": "entity",
"nullableList": []
});

expect(wld.id, 7);
expect(wld.name, "entity");
expect(wld.list.length, 2);
});

// previous hashing mechanism if you swapped the adjacent field values
// it wouldn't change the hash
test(
'hashing an object which has two fields of the same type is still different',
() {
var ht = HashTest(fieldOne: false, fieldTwo: true);
var ht1 = HashTest(fieldOne: true, fieldTwo: false);
var ht1 = HashTest(fieldTwo: false, fieldOne: true);
expect(false, ht.hashCode == ht1.hashCode);
});

test('additional properties mappings', () {
const addProp = {
'discrim': 'fred',
'readings': {'one': 1, 'two': 2.3},
'extra': {},
'dependencies': {
'deps1': ['a', 34.2, true],
'deps2': [17.8, false, 'b']
Expand Down Expand Up @@ -77,24 +95,24 @@ main() {

var ap = AddProps3.fromJson(addProp);
expect(ap.discrim, 'fred');
expect(ap.readings?.length, 2);
expect(ap.readings?['one'], 1);
expect(ap.readings?['two'], 2.3);
expect(ap.dependencies?['deps1'], ['a', 34.2, true]);
expect(ap.dependencies?['deps2'], [17.8, false, 'b']);
expect(ap.otherDeps?['name'], ['tom', 'dick', 'harry']);
expect(ap.otherDeps?['height'], [1.7, 1.3, 1.4]);
expect(ap.otherDeps?['info'], 'this is top secret');
expect(ap.yetMoreAdditional?['sList'], ['a', 'b', 'c']);
expect(ap.readings!.length, 2);
expect(ap.readings!['one'], 1);
expect(ap.readings!['two'], 2.3);
expect(ap.dependencies!['deps1'], ['a', 34.2, true]);
expect(ap.dependencies!['deps2'], [17.8, false, 'b']);
expect(ap.otherDeps!['name'], ['tom', 'dick', 'harry']);
expect(ap.otherDeps!['height'], [1.7, 1.3, 1.4]);
expect(ap.otherDeps!['info'], 'this is top secret');
expect(ap.yetMoreAdditional!['sList'], ['a', 'b', 'c']);
expect(
ap.mapWithComplexObject?['c1']?[0],
ap.mapWithComplexObject!['c1']?[0],
Event(
status: EventStatus.STREAMING,
id: 'xx',
title: 'Scully',
img: 'img',
imageUrl: 'http://blah'));
expect(ap.mapWithEnums?['statuses'],
expect(ap.mapWithEnums!['statuses'],
[EventStatus.STREAMING, EventStatus.CLOSED]);
});

Expand All @@ -116,6 +134,7 @@ main() {
'basicInt': 2.6,
'basicDouble': 1,
'intList': [1, 2.6],
'int64Int': 33,
'intMap': {'one': 1, 'two': 2.7},
'doubleList': [1, 2.6],
'doubleMap': {'one': 1, 'two': 2.7},
Expand All @@ -125,35 +144,33 @@ main() {
expect(data.basicDouble, 1.0);
expect(data.basicInt, 2);
expect(data.intList, [1, 2]);
expect(data.int64Int, 33);
expect(data.intMap, {'one': 1, 'two': 2});
expect(data.doubleList, [1.0, 2.6]);
expect(data.doubleMap, {'one': 1.0, 'two': 2.7});
});

test('basic inheritance', () {
final wld = WithListDerived.fromJson({
"list": [ {"id": 1, "name": "one"}, {"id": 2, "name": "two"} ],
"id": 7, "name": "entity",
"nullableList": []
});

expect(wld.id, 7);
expect(wld.name, "entity");
expect(wld.list.length, 2);
});

test('data serialisation', () {
final data = DoubleAndIntConversion(
basicInt: 43, basicDouble: 26.2, intList: [], doubleMap: {});
expect(data.toJson(),
{'basicInt': 43, 'basicDouble': 26.2, 'intList': [], 'doubleMap': {}});
int64Int: 0,
intMap: {},
basicInt: 43,
basicDouble: 26.2,
intList: [],
doubleMap: {});
expect(data.toJson(), {
'basicInt': 43,
'int64Int': 0,
'basicDouble': 26.2,
'intList': [],
'intMap': {},
'doubleList': [], // because it is not nullable
'doubleMap': {}
});
});

test("int enums being generated with correct type", () {
expect(IntTypeEnum.number1.toJson(), 1);
expect(IntTypeEnum.number1, IntTypeEnumExtension.fromJson(1));
});

test(
"enums included in a model via allOf with reference will be treated as"
"enums and generate valid code ", () {
Expand All @@ -162,7 +179,6 @@ main() {
expect(testO.name, "foobar");
expect(testO.enumFieldAllOf, NumericAndSpacedEnum.n667);
});

test("generating 2d array in a correct way", () {
const json = {
"coordinates": [
Expand All @@ -172,10 +188,10 @@ main() {
};
final geometry = PointGeometry.fromJson(json);
expect(geometry.coordinates, hasLength(2));
final firstPair = geometry.coordinates?.first;
final firstPair = geometry.coordinates.first;
expect(firstPair, hasLength(2));
expect(firstPair?[0], -27.6307582);
expect(firstPair?[1], 153.0401564);
expect(firstPair[0], -27.6307582);
expect(firstPair[1], 153.0401564);
});
}

Expand Down
Loading
Loading