Skip to content

Commit

Permalink
remove map assumption in fromJson
Browse files Browse the repository at this point in the history
  • Loading branch information
cedvdb committed Nov 21, 2024
1 parent d6ddaf4 commit ba39aa4
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 5 deletions.
3 changes: 3 additions & 0 deletions pkg/json/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 0.20.3
- Allow custom `fromJson` to have an arbitrary parameter type.

# 0.20.2

- Fix generated code syntax error when defining fields containing the dollar sign `$` by using raw strings.
Expand Down
8 changes: 4 additions & 4 deletions pkg/json/lib/json.dart
Original file line number Diff line number Diff line change
Expand Up @@ -384,16 +384,16 @@ mixin _FromJson on _Shared {
// Otherwise, check if `classDecl` has a `fromJson` constructor.
final constructors = await builder.constructorsOf(classDecl);
final fromJson = constructors
.firstWhereOrNull((c) => c.identifier.name == 'fromJson')
?.identifier;
.firstWhereOrNull((c) => c.identifier.name == 'fromJson');

if (fromJson != null) {
return RawCode.fromParts([
if (nullCheck != null) nullCheck,
fromJson,
fromJson.identifier,
'(',
jsonReference,
' as ',
introspectionData.jsonMapCode,
fromJson.positionalParameters.first.type.code,
')',
]);
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/json/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: >
`toJson` encoding method.
repository: https://github.com/dart-lang/sdk/tree/main/pkg/json
version: 0.20.2
version: 0.20.3
environment:
sdk: ^3.6.0-edge
dependencies:
Expand Down
115 changes: 115 additions & 0 deletions pkg/json/test/json_codable_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ void main() {
'mapOfSerializableField': {
'c': {'x': 3}
},
'customStringSerializationField': 'hi',
'customMapSerializationField': {
'z': 'zzz',
}
};

var a = A.fromJson(json);
Expand All @@ -36,6 +40,9 @@ void main() {
expect(a.listOfSerializableField.single.x, 1);
expect(a.setOfSerializableField.single.x, 2);
expect(a.mapOfSerializableField['c']!.x, 3);
expect(a.customStringSerializationField, CustomStringSerialization('hi'));
expect(
a.customMapSerializationField, CustomMapSerialization({'z': 'zzz'}));

expect(a.toJson(), equals(json));
});
Expand All @@ -56,6 +63,8 @@ void main() {
'nullableMapOfSerializableField': {
'd': {'x': 3},
},
'nullableCustomStringSerializationField': 'hi',
'nullableCustomMapSerializationField': {'z': 'zzz'},
};

var b = B.fromJson(json);
Expand All @@ -67,6 +76,10 @@ void main() {
expect(b.nullableListOfSerializableField!.single.x, 1);
expect(b.nullableSetOfSerializableField!.single.x, 2);
expect(b.nullableMapOfSerializableField!['d']!.x, 3);
expect(b.nullableCustomStringSerializationField,
CustomStringSerialization('hi'));
expect(b.nullableCustomMapSerializationField,
CustomMapSerialization({'z': 'zzz'}));

expect(b.toJson(), equals(json));
});
Expand All @@ -81,6 +94,8 @@ void main() {
'nullableListOfSerializableField': null,
'nullableSetOfSerializableField': null,
'nullableMapOfSerializableField': null,
'nullableCustomStringSerializationField': null,
'nullableCustomMapSerializationField': null,
});
expect(b.nullableBoolField, null);
expect(b.nullableStringField, null);
Expand All @@ -90,6 +105,8 @@ void main() {
expect(b.nullableListOfSerializableField, null);
expect(b.nullableMapOfSerializableField, null);
expect(b.nullableSetOfSerializableField, null);
expect(b.nullableCustomStringSerializationField, null);
expect(b.nullableCustomMapSerializationField, null);

expect(b.toJson(), isEmpty);
});
Expand All @@ -104,6 +121,8 @@ void main() {
expect(b.nullableListOfSerializableField, null);
expect(b.nullableMapOfSerializableField, null);
expect(b.nullableSetOfSerializableField, null);
expect(b.nullableCustomStringSerializationField, null);
expect(b.nullableCustomMapSerializationField, null);

expect(b.toJson(), isEmpty);
});
Expand Down Expand Up @@ -131,6 +150,11 @@ void main() {
null,
{'a': 1, 'b': null},
],
'listOfCustomStringSerializables': [null, 'hi'],
'listOfCustomMapSerializables': [
null,
{'z': 'zzz'}
],
'setOfNullableInts': [
null,
2,
Expand All @@ -146,6 +170,11 @@ void main() {
'b': null,
},
],
'setOfCustomStringSerializables': [null, 'hi'],
'setOfCustomMapSerializables': [
null,
{'z': 'zzz'}
],
'mapOfNullableInts': {
'a': 3,
'b': null,
Expand All @@ -158,6 +187,14 @@ void main() {
'a': [null, 3],
'b': null,
},
'mapOfCustomStringSerializables': {
'a': null,
'b': 'hi',
},
'mapOfCustomMapSerializables': {
'a': null,
'b': {'z': 'zzz'},
},
};

var e = E.fromJson(json);
Expand All @@ -170,6 +207,13 @@ void main() {
null,
{'a': 1, 'b': null},
]));
expect(e.listOfCustomStringSerializables.first, null);
expect(e.listOfCustomStringSerializables[1],
CustomStringSerialization('hi'));
expect(e.listOfCustomMapSerializables.first, null);
expect(e.listOfCustomMapSerializables[1],
CustomMapSerialization({'z': 'zzz'}));

expect(e.setOfNullableInts, equals({null, 2}));
expect(e.setOfNullableSerializables.first!.x, 2);
expect(e.setOfNullableSerializables.elementAt(1), null);
Expand All @@ -182,6 +226,13 @@ void main() {
'b': null,
},
}));
expect(e.setOfCustomStringSerializables.first, null);
expect(e.setOfCustomStringSerializables.toList()[1],
CustomStringSerialization('hi'));
expect(e.setOfCustomMapSerializables.first, null);
expect(e.setOfCustomMapSerializables.toList()[1],
CustomMapSerialization({'z': 'zzz'}));

expect(
e.mapOfNullableInts,
equals({
Expand All @@ -195,6 +246,12 @@ void main() {
'a': {null, 3},
'b': null,
});
expect(e.mapOfCustomStringSerializables?['a'], null);
expect(e.mapOfCustomStringSerializables?['b'],
CustomStringSerialization('hi'));
expect(e.mapOfCustomMapSerializables?['a'], null);
expect(e.mapOfCustomMapSerializables?['b'],
CustomMapSerialization({'z': 'zzz'}));

expect(e.toJson(), equals(json));
});
Expand Down Expand Up @@ -228,6 +285,10 @@ class A {
final Set<C> setOfSerializableField;

final Map<String, C> mapOfSerializableField;

final CustomStringSerialization customStringSerializationField;

final CustomMapSerialization customMapSerializationField;
}

@JsonCodable()
Expand All @@ -247,6 +308,10 @@ class B {
final Set<C>? nullableSetOfSerializableField;

final Map<String, C>? nullableMapOfSerializableField;

final CustomStringSerialization? nullableCustomStringSerializationField;

final CustomMapSerialization? nullableCustomMapSerializationField;
}

@JsonCodable()
Expand All @@ -267,20 +332,70 @@ class E {

final List<Map<String, int?>?> listOfNullableMapsOfNullableInts;

final List<CustomStringSerialization?> listOfCustomStringSerializables;

final List<CustomMapSerialization?> listOfCustomMapSerializables;

final Set<int?> setOfNullableInts;

final Set<C?> setOfNullableSerializables;

final Set<Map<String, int?>?> setOfNullableMapsOfNullableInts;

final Set<CustomStringSerialization?> setOfCustomStringSerializables;

final Set<CustomMapSerialization?> setOfCustomMapSerializables;

final Map<String, int?> mapOfNullableInts;

final Map<String, C?> mapOfNullableSerializables;

final Map<String, Set<int?>?> mapOfNullableSetsOfNullableInts;

final Map<String, CustomStringSerialization?> mapOfCustomStringSerializables;

final Map<String, CustomMapSerialization?> mapOfCustomMapSerializables;
}

@JsonCodable()
class F {
final int fieldWithDollarSign$;
}

class CustomStringSerialization {
final String a;

CustomStringSerialization(this.a);

String toJson() => a;

factory CustomStringSerialization.fromJson(String a) =>
CustomStringSerialization(a);

@override
bool operator ==(Object other) =>
other is CustomStringSerialization && a == other.a;

@override
int get hashCode => a.hashCode;
}

class CustomMapSerialization {
final Map<String, dynamic> a;

CustomMapSerialization(this.a);

Map<String, dynamic> toJson() => a;

factory CustomMapSerialization.fromJson(Map<String, dynamic> a) =>
CustomMapSerialization(a);

@override
bool operator ==(Object other) {
return other is CustomMapSerialization &&
a.toString() == other.a.toString();
}

@override
int get hashCode => a.hashCode;
}

0 comments on commit ba39aa4

Please sign in to comment.