Created by: 0xNF
fixes #12165 (closed)
This PR includes a patch to the modules/openapi-generator/src/main/resources/dart2/serialization/native/native_class.mustache
file which previously wasn't handling the deserialiation of Map<String, Object>
types correctly.
Previously, the deserialization of such fields was being generated as mapValueOfType<Map<String, Object>>(json, key)
, but due to Dart using different internal map representations, this would always fail at runtime, meaning that such objects were not able to be generated by this project.
This change adjusts the mustache file to detect when a field is a complex map and uses mapCastOfType<String, Object>(json[key])
instead, which does not crash at runtime.
The correctness of the change can be confirmed using the following test files:
spec.yaml:
openapi: 3.0.3
info:
version: "1.1"
title: Dart AdditionaProperties True
servers:
- url: 'localhost'
variables:
host:
default: localhost
components:
schemas:
ItemsWithMapStringAnyWithPropsTrue:
type: object
description: "map-string-any defined with `additionalProperties: true`"
properties:
objectMap:
type: object
additionalProperties: true
ItemWithMapStringAnyWithPropsObject:
type: object
description: "map-string-any defined with `additionalProperties: object`"
properties:
objectMap:
type: object
additionalProperties:
type: object
paths:
/items:
get:
operationId: GetItemWithMapStringObjects
responses:
"200":
description: A list of ItemWithMapStringObject
content:
application/json:
schema:
$ref: '#/components/schemas/ItemWithMapStringAnyWithPropsObject'
Dart test file
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
import 'dart:convert';
import 'package:openapi/api.dart';
import 'package:test/test.dart';
// tests for ItemWithMapStringAnyWithPropsObject
void main() {
// final instance = ItemWithMapStringAnyWithPropsObject();
final String s = '{"objectMap": {"item_int": 1, "item_bool": true, "item_string": "str", "item_double": 4.3, "item_map": {"subProps": 1}, "item_array": [-1]}}';
group('test ItemWithMapStringAnyWithPropsObject', () {
// Map<String, Object> objectMap (default value: const {})
test('to test the property `objectMap`', () async {
final m = JsonDecoder().convert(s);
final i = ItemsWithMapStringAnyWithPropsTrue.fromJson(m)!;
assert(i.objectMap["item_int"] == 1);
assert(i.objectMap["item_bool"] == true);
assert(i.objectMap["item_string"] == "str");
assert(i.objectMap["item_double"] == 4.3);
assert((i.objectMap["item_map"] as Map)["subProps"] == 1);
assert((i.objectMap["item_array"] as List)[0] == -1);
});
test('to test the property `objectMap`', () async {
final m = JsonDecoder().convert(s);
final i = ItemWithMapStringAnyWithPropsObject.fromJson(m)!;
assert(i.objectMap["item_int"] == 1);
assert(i.objectMap["item_bool"] == true);
assert(i.objectMap["item_string"] == "str");
assert(i.objectMap["item_double"] == 4.3);
assert((i.objectMap["item_map"] as Map)["subProps"] == 1);
assert((i.objectMap["item_array"] as List)[0] == -1);
});
});
}
@jaumard @josh-burton @amondnet @sbu-WBT @kuhnroyal @agilob @ahmednfwela