Skip to content

Commit 2c93b3c

Browse files
authored
Support int literals in JSON content being assigned to double fields (#34)
Right now `{'value': 0}` cannot be assigned to a double. Also improve types a bit in test_utils
1 parent 3736d3e commit 2c93b3c

File tree

6 files changed

+70
-2
lines changed

6 files changed

+70
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Simplify the serialization of `Map` instances when no conversion is required
44
for `values`.
55

6+
* Handle `int` literals in JSON being assigned to `double` fields.
7+
68
## 0.2.2
79

810
* Enable support for `enum` values.

lib/src/type_helpers/value_helper.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:analyzer/dart/element/type.dart';
2+
import 'package:source_gen/source_gen.dart' show TypeChecker;
23
import '../type_helper.dart';
34

45
class ValueHelper extends TypeHelper {
@@ -20,6 +21,9 @@ class ValueHelper extends TypeHelper {
2021
if (targetType.isDynamic || targetType.isObject) {
2122
// just return it as-is. We'll hope it's safe.
2223
return expression;
24+
} else if (const TypeChecker.fromRuntime(double)
25+
.isExactlyType(targetType)) {
26+
return '($expression as num).toDouble()';
2327
} else if (simpleJsonTypeChecker.isAssignableFromType(targetType)) {
2428
return '$expression as $targetType';
2529
}

test/json_serializable_integration_test.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,34 @@ void main() {
104104
roundTripItem(item);
105105
});
106106
});
107+
108+
group('Numbers', () {
109+
roundTripNumber(Numbers p) {
110+
roundTripObject(p, (json) => new Numbers.fromJson(json));
111+
}
112+
113+
test('simple', () {
114+
roundTripNumber(new Numbers()
115+
..nums = [0, 0.0]
116+
..doubles = [0.0]
117+
..ints = [0]);
118+
});
119+
120+
test('support ints as doubles', () {
121+
var value = {
122+
'doubles': [0, 0.0]
123+
};
124+
125+
roundTripNumber(new Numbers.fromJson(value));
126+
});
127+
128+
test('does not support doubles as ints', () {
129+
var value = {
130+
'ints': [0.0, 0],
131+
};
132+
133+
expect(() => new Numbers.fromJson(value),
134+
throwsA(new isInstanceOf<CastError>()));
135+
});
136+
});
107137
}

test/test_files/json_test_example.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,21 @@ class Platform {
102102

103103
String toJson() => description;
104104
}
105+
106+
@JsonSerializable()
107+
class Numbers extends Object with _$NumbersSerializerMixin {
108+
List<int> ints;
109+
List<num> nums;
110+
List<double> doubles;
111+
112+
Numbers();
113+
114+
factory Numbers.fromJson(Map<String, dynamic> json) =>
115+
_$NumbersFromJson(json);
116+
117+
bool operator ==(Object other) =>
118+
other is Numbers &&
119+
_deepEquals(ints, other.ints) &&
120+
_deepEquals(nums, other.nums) &&
121+
_deepEquals(doubles, other.doubles);
122+
}

test/test_files/json_test_example.g.dart

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/test_utils.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Iterable<Element> _getElements(CompilationUnitMember member) {
7373
return [element];
7474
}
7575

76-
void roundTripObject(object, factory(Map<String, dynamic> json)) {
76+
void roundTripObject<T>(T object, T factory(Map<String, dynamic> json)) {
7777
var json = loudEncode(object);
7878

7979
var person2 = factory(JSON.decode(json) as Map<String, dynamic>);
@@ -86,7 +86,7 @@ void roundTripObject(object, factory(Map<String, dynamic> json)) {
8686
}
8787

8888
/// Prints out nested causes before throwing `JsonUnsupportedObjectError`.
89-
String loudEncode(object) {
89+
String loudEncode(Object object) {
9090
try {
9191
return const JsonEncoder.withIndent(' ').convert(object);
9292
} on JsonUnsupportedObjectError catch (e) {

0 commit comments

Comments
 (0)