diff --git a/jsonexample/lib/built_value/built_complex_object.dart b/jsonexample/lib/built_value/built_complex_object.dart index baeaf815864..ef337cd9d49 100644 --- a/jsonexample/lib/built_value/built_complex_object.dart +++ b/jsonexample/lib/built_value/built_complex_object.dart @@ -23,14 +23,19 @@ abstract class BuiltComplexObject @nullable double get aDouble; + @nullable BuiltSimpleObject get anObject; + @nullable BuiltList get aListOfStrings; + @nullable BuiltList get aListOfInts; + @nullable BuiltList get aListOfDoubles; + @nullable BuiltList get aListOfObjects; BuiltComplexObject._(); diff --git a/jsonexample/lib/built_value/built_complex_object.g.dart b/jsonexample/lib/built_value/built_complex_object.g.dart index e3dc6681563..51aeb6f976f 100644 --- a/jsonexample/lib/built_value/built_complex_object.g.dart +++ b/jsonexample/lib/built_value/built_complex_object.g.dart @@ -7,7 +7,7 @@ part of 'built_complex_object.dart'; // ************************************************************************** -// Generator: BuiltValueGenerator +// BuiltValueGenerator // ************************************************************************** // ignore_for_file: always_put_control_body_on_new_line @@ -31,27 +31,7 @@ class _$BuiltComplexObjectSerializer @override Iterable serialize(Serializers serializers, BuiltComplexObject object, {FullType specifiedType: FullType.unspecified}) { - final result = [ - 'anObject', - serializers.serialize(object.anObject, - specifiedType: const FullType(BuiltSimpleObject)), - 'aListOfStrings', - serializers.serialize(object.aListOfStrings, - specifiedType: - const FullType(BuiltList, const [const FullType(String)])), - 'aListOfInts', - serializers.serialize(object.aListOfInts, - specifiedType: - const FullType(BuiltList, const [const FullType(int)])), - 'aListOfDoubles', - serializers.serialize(object.aListOfDoubles, - specifiedType: - const FullType(BuiltList, const [const FullType(double)])), - 'aListOfObjects', - serializers.serialize(object.aListOfObjects, - specifiedType: const FullType( - BuiltList, const [const FullType(BuiltSimpleObject)])), - ]; + final result = []; if (object.aString != null) { result ..add('aString') @@ -70,6 +50,40 @@ class _$BuiltComplexObjectSerializer ..add(serializers.serialize(object.aDouble, specifiedType: const FullType(double))); } + if (object.anObject != null) { + result + ..add('anObject') + ..add(serializers.serialize(object.anObject, + specifiedType: const FullType(BuiltSimpleObject))); + } + if (object.aListOfStrings != null) { + result + ..add('aListOfStrings') + ..add(serializers.serialize(object.aListOfStrings, + specifiedType: + const FullType(BuiltList, const [const FullType(String)]))); + } + if (object.aListOfInts != null) { + result + ..add('aListOfInts') + ..add(serializers.serialize(object.aListOfInts, + specifiedType: + const FullType(BuiltList, const [const FullType(int)]))); + } + if (object.aListOfDoubles != null) { + result + ..add('aListOfDoubles') + ..add(serializers.serialize(object.aListOfDoubles, + specifiedType: + const FullType(BuiltList, const [const FullType(double)]))); + } + if (object.aListOfObjects != null) { + result + ..add('aListOfObjects') + ..add(serializers.serialize(object.aListOfObjects, + specifiedType: const FullType( + BuiltList, const [const FullType(BuiltSimpleObject)]))); + } return result; } @@ -163,21 +177,7 @@ class _$BuiltComplexObject extends BuiltComplexObject { this.aListOfInts, this.aListOfDoubles, this.aListOfObjects}) - : super._() { - if (anObject == null) - throw new BuiltValueNullFieldError('BuiltComplexObject', 'anObject'); - if (aListOfStrings == null) - throw new BuiltValueNullFieldError( - 'BuiltComplexObject', 'aListOfStrings'); - if (aListOfInts == null) - throw new BuiltValueNullFieldError('BuiltComplexObject', 'aListOfInts'); - if (aListOfDoubles == null) - throw new BuiltValueNullFieldError( - 'BuiltComplexObject', 'aListOfDoubles'); - if (aListOfObjects == null) - throw new BuiltValueNullFieldError( - 'BuiltComplexObject', 'aListOfObjects'); - } + : super._(); @override BuiltComplexObject rebuild(void updates(BuiltComplexObjectBuilder b)) => @@ -315,24 +315,24 @@ class BuiltComplexObjectBuilder aString: aString, anInt: anInt, aDouble: aDouble, - anObject: anObject.build(), - aListOfStrings: aListOfStrings.build(), - aListOfInts: aListOfInts.build(), - aListOfDoubles: aListOfDoubles.build(), - aListOfObjects: aListOfObjects.build()); + anObject: _anObject?.build(), + aListOfStrings: _aListOfStrings?.build(), + aListOfInts: _aListOfInts?.build(), + aListOfDoubles: _aListOfDoubles?.build(), + aListOfObjects: _aListOfObjects?.build()); } catch (_) { String _$failedField; try { _$failedField = 'anObject'; - anObject.build(); + _anObject?.build(); _$failedField = 'aListOfStrings'; - aListOfStrings.build(); + _aListOfStrings?.build(); _$failedField = 'aListOfInts'; - aListOfInts.build(); + _aListOfInts?.build(); _$failedField = 'aListOfDoubles'; - aListOfDoubles.build(); + _aListOfDoubles?.build(); _$failedField = 'aListOfObjects'; - aListOfObjects.build(); + _aListOfObjects?.build(); } catch (e) { throw new BuiltValueNestedFieldError( 'BuiltComplexObject', _$failedField, e.toString()); diff --git a/jsonexample/lib/built_value/built_simple_object.dart b/jsonexample/lib/built_value/built_simple_object.dart index 297c5fb65b1..84dee0a4e4c 100644 --- a/jsonexample/lib/built_value/built_simple_object.dart +++ b/jsonexample/lib/built_value/built_simple_object.dart @@ -22,10 +22,13 @@ abstract class BuiltSimpleObject @nullable double get aDouble; + @nullable BuiltList get aListOfStrings; + @nullable BuiltList get aListOfInts; + @nullable BuiltList get aListOfDoubles; BuiltSimpleObject._(); diff --git a/jsonexample/lib/built_value/built_simple_object.g.dart b/jsonexample/lib/built_value/built_simple_object.g.dart index 9c91fbe7f91..16ebd2eec0f 100644 --- a/jsonexample/lib/built_value/built_simple_object.g.dart +++ b/jsonexample/lib/built_value/built_simple_object.g.dart @@ -7,7 +7,7 @@ part of 'built_simple_object.dart'; // ************************************************************************** -// Generator: BuiltValueGenerator +// BuiltValueGenerator // ************************************************************************** // ignore_for_file: always_put_control_body_on_new_line @@ -31,20 +31,7 @@ class _$BuiltSimpleObjectSerializer @override Iterable serialize(Serializers serializers, BuiltSimpleObject object, {FullType specifiedType: FullType.unspecified}) { - final result = [ - 'aListOfStrings', - serializers.serialize(object.aListOfStrings, - specifiedType: - const FullType(BuiltList, const [const FullType(String)])), - 'aListOfInts', - serializers.serialize(object.aListOfInts, - specifiedType: - const FullType(BuiltList, const [const FullType(int)])), - 'aListOfDoubles', - serializers.serialize(object.aListOfDoubles, - specifiedType: - const FullType(BuiltList, const [const FullType(double)])), - ]; + final result = []; if (object.aString != null) { result ..add('aString') @@ -63,6 +50,27 @@ class _$BuiltSimpleObjectSerializer ..add(serializers.serialize(object.aDouble, specifiedType: const FullType(double))); } + if (object.aListOfStrings != null) { + result + ..add('aListOfStrings') + ..add(serializers.serialize(object.aListOfStrings, + specifiedType: + const FullType(BuiltList, const [const FullType(String)]))); + } + if (object.aListOfInts != null) { + result + ..add('aListOfInts') + ..add(serializers.serialize(object.aListOfInts, + specifiedType: + const FullType(BuiltList, const [const FullType(int)]))); + } + if (object.aListOfDoubles != null) { + result + ..add('aListOfDoubles') + ..add(serializers.serialize(object.aListOfDoubles, + specifiedType: + const FullType(BuiltList, const [const FullType(double)]))); + } return result; } @@ -139,14 +147,7 @@ class _$BuiltSimpleObject extends BuiltSimpleObject { this.aListOfStrings, this.aListOfInts, this.aListOfDoubles}) - : super._() { - if (aListOfStrings == null) - throw new BuiltValueNullFieldError('BuiltSimpleObject', 'aListOfStrings'); - if (aListOfInts == null) - throw new BuiltValueNullFieldError('BuiltSimpleObject', 'aListOfInts'); - if (aListOfDoubles == null) - throw new BuiltValueNullFieldError('BuiltSimpleObject', 'aListOfDoubles'); - } + : super._(); @override BuiltSimpleObject rebuild(void updates(BuiltSimpleObjectBuilder b)) => @@ -262,18 +263,18 @@ class BuiltSimpleObjectBuilder aString: aString, anInt: anInt, aDouble: aDouble, - aListOfStrings: aListOfStrings.build(), - aListOfInts: aListOfInts.build(), - aListOfDoubles: aListOfDoubles.build()); + aListOfStrings: _aListOfStrings?.build(), + aListOfInts: _aListOfInts?.build(), + aListOfDoubles: _aListOfDoubles?.build()); } catch (_) { String _$failedField; try { _$failedField = 'aListOfStrings'; - aListOfStrings.build(); + _aListOfStrings?.build(); _$failedField = 'aListOfInts'; - aListOfInts.build(); + _aListOfInts?.build(); _$failedField = 'aListOfDoubles'; - aListOfDoubles.build(); + _aListOfDoubles?.build(); } catch (e) { throw new BuiltValueNestedFieldError( 'BuiltSimpleObject', _$failedField, e.toString()); diff --git a/jsonexample/lib/built_value/built_value_serializers.g.dart b/jsonexample/lib/built_value/built_value_serializers.g.dart index 5fa2ddb28a8..cd4549bf7d2 100644 --- a/jsonexample/lib/built_value/built_value_serializers.g.dart +++ b/jsonexample/lib/built_value/built_value_serializers.g.dart @@ -7,7 +7,7 @@ part of serializers; // ************************************************************************** -// Generator: BuiltValueGenerator +// BuiltValueGenerator // ************************************************************************** // ignore_for_file: always_put_control_body_on_new_line diff --git a/jsonexample/lib/json_serializable/serializable_complex_object.g.dart b/jsonexample/lib/json_serializable/serializable_complex_object.g.dart index 21bce9abf66..d0276765839 100644 --- a/jsonexample/lib/json_serializable/serializable_complex_object.g.dart +++ b/jsonexample/lib/json_serializable/serializable_complex_object.g.dart @@ -7,7 +7,7 @@ part of 'serializable_complex_object.dart'; // ************************************************************************** -// Generator: JsonSerializableGenerator +// JsonSerializableGenerator // ************************************************************************** SerializableComplexObject _$SerializableComplexObjectFromJson( diff --git a/jsonexample/lib/json_serializable/serializable_simple_object.g.dart b/jsonexample/lib/json_serializable/serializable_simple_object.g.dart index d4a2c188713..e985450b94f 100644 --- a/jsonexample/lib/json_serializable/serializable_simple_object.g.dart +++ b/jsonexample/lib/json_serializable/serializable_simple_object.g.dart @@ -7,7 +7,7 @@ part of 'serializable_simple_object.dart'; // ************************************************************************** -// Generator: JsonSerializableGenerator +// JsonSerializableGenerator // ************************************************************************** SerializableSimpleObject _$SerializableSimpleObjectFromJson( diff --git a/jsonexample/lib/tab_pages.dart b/jsonexample/lib/tab_pages.dart index ba61a8b3fa8..590f1bc4310 100644 --- a/jsonexample/lib/tab_pages.dart +++ b/jsonexample/lib/tab_pages.dart @@ -104,7 +104,7 @@ class BasicsPage extends StatelessWidget { children: [ Padding( padding: const EdgeInsets.only(right: 8.0, bottom: 4.0), - child: Text('List of dynamic:', style: boldStyle), + child: Text('List of dynamics:', style: boldStyle), ), Text( prettyPrintList(strongListOfDynamics), diff --git a/jsonexample/test/complex_object_unit_test.dart b/jsonexample/test/complex_object_unit_test.dart new file mode 100644 index 00000000000..dcb44227b67 --- /dev/null +++ b/jsonexample/test/complex_object_unit_test.dart @@ -0,0 +1,422 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:jsonexample/built_value/built_complex_object.dart'; +import 'package:jsonexample/built_value/built_value_serializers.dart'; +import 'package:jsonexample/dart_convert/converted_complex_object.dart'; +import 'package:jsonexample/json_serializable/serializable_complex_object.dart'; + +void main() { + const typicalObjectJson = { + 'aString': 'Blah, blah, blah.', + 'anInt': 1, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0], + 'anObject': { + 'aString': 'Blah, blah, blah.', + 'anInt': 1, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0] + }, + 'aListOfObjects': [ + { + 'aString': 'Blah, blah, blah.', + 'anInt': 1, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0] + }, + { + 'aString': 'Blah, blah, blah.', + 'anInt': 2, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0] + }, + { + 'aString': 'Blah, blah, blah.', + 'anInt': 3, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0] + } + ] + }; + + const emptySimpleObjectsJson = { + 'aString': 'Blah, blah, blah.', + 'anInt': 1, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0], + 'anObject': {}, + 'aListOfObjects': [ + {}, + {}, + {} + ] + }; + + const unexpectedPropertiesJson = { + 'aString': 'Blah, blah, blah.', + 'anInt': 1, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0], + 'unexpectedProperty': 'Whoops!', + 'anObject': { + 'aString': 'Blah, blah, blah.', + 'anInt': 1, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0], + 'unexpectedProperty': 'Whoops!' + }, + 'aListOfObjects': [ + { + 'aString': 'Blah, blah, blah.', + 'anInt': 1, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0], + 'unexpectedProperty': 'Whoops!' + }, + { + 'aString': 'Blah, blah, blah.', + 'anInt': 2, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0], + 'unexpectedProperty': 'Whoops!' + }, + { + 'aString': 'Blah, blah, blah.', + 'anInt': 3, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0], + 'unexpectedProperty': 'Whoops!' + } + ] + }; + + const emptyJson = {}; + + group('ConvertedComplexObject unit tests', () { + test('Typical object is converted correctly', () { + final complexObject = ConvertedComplexObject.fromJson(typicalObjectJson); + + expect(complexObject.aString, "Blah, blah, blah."); + expect(complexObject.anInt, 1); + expect(complexObject.aDouble, 1.0); + expect(complexObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.anObject.aString, "Blah, blah, blah."); + expect(complexObject.anObject.anInt, 1); + expect(complexObject.anObject.aDouble, 1.0); + expect(complexObject.anObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.anObject.aListOfInts, [1, 2, 3]); + expect(complexObject.anObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.aListOfObjects.length, 3); + + for (int i = 0; i < 3; i++) { + expect(complexObject.aListOfObjects[i].aString, "Blah, blah, blah."); + expect(complexObject.aListOfObjects[i].anInt, i + 1); + expect(complexObject.aListOfObjects[i].aDouble, 1.0); + expect(complexObject.aListOfObjects[i].aListOfStrings, + ['one', 'two', 'three']); + expect(complexObject.aListOfObjects[i].aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfObjects[i].aListOfDoubles, [1.0, 2.0, 3.0]); + } + }); + + test('Empty object results in null fields', () { + final complexObject = ConvertedComplexObject.fromJson(emptyJson); + + expect(complexObject.aString, isNull); + expect(complexObject.anInt, isNull); + expect(complexObject.aDouble, isNull); + expect(complexObject.aListOfStrings, isNull); + expect(complexObject.aListOfInts, isNull); + expect(complexObject.aListOfDoubles, isNull); + expect(complexObject.anObject, isNull); + expect(complexObject.aListOfObjects, isNull); + }); + + test('Empty simple objects result in instances with null fields', () { + final complexObject = + ConvertedComplexObject.fromJson(emptySimpleObjectsJson); + + expect(complexObject.aString, "Blah, blah, blah."); + expect(complexObject.anInt, 1); + expect(complexObject.aDouble, 1.0); + expect(complexObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.anObject.aString, isNull); + expect(complexObject.anObject.anInt, isNull); + expect(complexObject.anObject.aDouble, isNull); + expect(complexObject.anObject.aListOfStrings, isNull); + expect(complexObject.anObject.aListOfInts, isNull); + expect(complexObject.anObject.aListOfDoubles, isNull); + expect(complexObject.aListOfObjects.length, 3); + + for (int i = 0; i < 3; i++) { + expect(complexObject.aListOfObjects[i].aString, isNull); + expect(complexObject.aListOfObjects[i].anInt, isNull); + expect(complexObject.aListOfObjects[i].aDouble, isNull); + expect(complexObject.aListOfObjects[i].aListOfStrings, isNull); + expect(complexObject.aListOfObjects[i].aListOfInts, isNull); + expect(complexObject.aListOfObjects[i].aListOfDoubles, isNull); + } + }); + + test('Unexpected properties are ignored', () { + final complexObject = + ConvertedComplexObject.fromJson(unexpectedPropertiesJson); + + expect(complexObject.aString, "Blah, blah, blah."); + expect(complexObject.anInt, 1); + expect(complexObject.aDouble, 1.0); + expect(complexObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.anObject.aString, "Blah, blah, blah."); + expect(complexObject.anObject.anInt, 1); + expect(complexObject.anObject.aDouble, 1.0); + expect(complexObject.anObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.anObject.aListOfInts, [1, 2, 3]); + expect(complexObject.anObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.aListOfObjects.length, 3); + + for (int i = 0; i < 3; i++) { + expect(complexObject.aListOfObjects[i].aString, "Blah, blah, blah."); + expect(complexObject.aListOfObjects[i].anInt, i + 1); + expect(complexObject.aListOfObjects[i].aDouble, 1.0); + expect(complexObject.aListOfObjects[i].aListOfStrings, + ['one', 'two', 'three']); + expect(complexObject.aListOfObjects[i].aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfObjects[i].aListOfDoubles, [1.0, 2.0, 3.0]); + } + }); + }); + + group('SerializableComplexObject unit tests', () { + test('Typical object is converted correctly', () { + final complexObject = + SerializableComplexObject.fromJson(typicalObjectJson); + + expect(complexObject.aString, "Blah, blah, blah."); + expect(complexObject.anInt, 1); + expect(complexObject.aDouble, 1.0); + expect(complexObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.anObject.aString, "Blah, blah, blah."); + expect(complexObject.anObject.anInt, 1); + expect(complexObject.anObject.aDouble, 1.0); + expect(complexObject.anObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.anObject.aListOfInts, [1, 2, 3]); + expect(complexObject.anObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.aListOfObjects.length, 3); + + for (int i = 0; i < 3; i++) { + expect(complexObject.aListOfObjects[i].aString, "Blah, blah, blah."); + expect(complexObject.aListOfObjects[i].anInt, i + 1); + expect(complexObject.aListOfObjects[i].aDouble, 1.0); + expect(complexObject.aListOfObjects[i].aListOfStrings, + ['one', 'two', 'three']); + expect(complexObject.aListOfObjects[i].aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfObjects[i].aListOfDoubles, [1.0, 2.0, 3.0]); + } + }); + + test('Empty object results in null fields', () { + final complexObject = SerializableComplexObject.fromJson(emptyJson); + + expect(complexObject.aString, isNull); + expect(complexObject.anInt, isNull); + expect(complexObject.aDouble, isNull); + expect(complexObject.aListOfStrings, isNull); + expect(complexObject.aListOfInts, isNull); + expect(complexObject.aListOfDoubles, isNull); + expect(complexObject.anObject, isNull); + expect(complexObject.aListOfObjects, isNull); + }); + + test('Empty simple objects result in instances with null fields', () { + final complexObject = + SerializableComplexObject.fromJson(emptySimpleObjectsJson); + + expect(complexObject.aString, "Blah, blah, blah."); + expect(complexObject.anInt, 1); + expect(complexObject.aDouble, 1.0); + expect(complexObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.anObject.aString, isNull); + expect(complexObject.anObject.anInt, isNull); + expect(complexObject.anObject.aDouble, isNull); + expect(complexObject.anObject.aListOfStrings, isNull); + expect(complexObject.anObject.aListOfInts, isNull); + expect(complexObject.anObject.aListOfDoubles, isNull); + expect(complexObject.aListOfObjects.length, 3); + + for (int i = 0; i < 3; i++) { + expect(complexObject.aListOfObjects[i].aString, isNull); + expect(complexObject.aListOfObjects[i].anInt, isNull); + expect(complexObject.aListOfObjects[i].aDouble, isNull); + expect(complexObject.aListOfObjects[i].aListOfStrings, isNull); + expect(complexObject.aListOfObjects[i].aListOfInts, isNull); + expect(complexObject.aListOfObjects[i].aListOfDoubles, isNull); + } + }); + + test('Unexpected properties are ignored', () { + final complexObject = + SerializableComplexObject.fromJson(unexpectedPropertiesJson); + + expect(complexObject.aString, "Blah, blah, blah."); + expect(complexObject.anInt, 1); + expect(complexObject.aDouble, 1.0); + expect(complexObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.anObject.aString, "Blah, blah, blah."); + expect(complexObject.anObject.anInt, 1); + expect(complexObject.anObject.aDouble, 1.0); + expect(complexObject.anObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.anObject.aListOfInts, [1, 2, 3]); + expect(complexObject.anObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.aListOfObjects.length, 3); + + for (int i = 0; i < 3; i++) { + expect(complexObject.aListOfObjects[i].aString, "Blah, blah, blah."); + expect(complexObject.aListOfObjects[i].anInt, i + 1); + expect(complexObject.aListOfObjects[i].aDouble, 1.0); + expect(complexObject.aListOfObjects[i].aListOfStrings, + ['one', 'two', 'three']); + expect(complexObject.aListOfObjects[i].aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfObjects[i].aListOfDoubles, [1.0, 2.0, 3.0]); + } + }); + }); + + group('BuiltComplexObject unit tests', () { + test('Typical object is converted correctly', () { + final complexObject = serializers.deserializeWith( + BuiltComplexObject.serializer, typicalObjectJson); + + expect(complexObject.aString, "Blah, blah, blah."); + expect(complexObject.anInt, 1); + expect(complexObject.aDouble, 1.0); + expect(complexObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.anObject.aString, "Blah, blah, blah."); + expect(complexObject.anObject.anInt, 1); + expect(complexObject.anObject.aDouble, 1.0); + expect(complexObject.anObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.anObject.aListOfInts, [1, 2, 3]); + expect(complexObject.anObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.aListOfObjects.length, 3); + + for (int i = 0; i < 3; i++) { + expect(complexObject.aListOfObjects[i].aString, "Blah, blah, blah."); + expect(complexObject.aListOfObjects[i].anInt, i + 1); + expect(complexObject.aListOfObjects[i].aDouble, 1.0); + expect(complexObject.aListOfObjects[i].aListOfStrings, + ['one', 'two', 'three']); + expect(complexObject.aListOfObjects[i].aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfObjects[i].aListOfDoubles, [1.0, 2.0, 3.0]); + } + }); + + test('Empty object results in null fields', () { + final complexObject = + serializers.deserializeWith(BuiltComplexObject.serializer, emptyJson); + + expect(complexObject.aString, isNull); + expect(complexObject.anInt, isNull); + expect(complexObject.aDouble, isNull); + expect(complexObject.anObject, isNull); + expect(complexObject.aListOfStrings, isNull); + expect(complexObject.aListOfInts, isNull); + expect(complexObject.aListOfDoubles, isNull); + expect(complexObject.aListOfObjects, isNull); + }); + + test('Empty simple objects result in instances with null fields', () { + final complexObject = serializers.deserializeWith( + BuiltComplexObject.serializer, emptySimpleObjectsJson); + + expect(complexObject.aString, "Blah, blah, blah."); + expect(complexObject.anInt, 1); + expect(complexObject.aDouble, 1.0); + expect(complexObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.anObject.aString, isNull); + expect(complexObject.anObject.anInt, isNull); + expect(complexObject.anObject.aDouble, isNull); + expect(complexObject.anObject.aListOfStrings, isNull); + expect(complexObject.anObject.aListOfInts, isNull); + expect(complexObject.anObject.aListOfDoubles, isNull); + expect(complexObject.aListOfObjects.length, 3); + + for (int i = 0; i < 3; i++) { + expect(complexObject.aListOfObjects[i].aString, isNull); + expect(complexObject.aListOfObjects[i].anInt, isNull); + expect(complexObject.aListOfObjects[i].aDouble, isNull); + expect(complexObject.aListOfObjects[i].aListOfStrings, isNull); + expect(complexObject.aListOfObjects[i].aListOfInts, isNull); + expect(complexObject.aListOfObjects[i].aListOfDoubles, isNull); + } + }); + + test('Unexpected properties are ignored', () { + final complexObject = serializers.deserializeWith( + BuiltComplexObject.serializer, unexpectedPropertiesJson); + + expect(complexObject.aString, "Blah, blah, blah."); + expect(complexObject.anInt, 1); + expect(complexObject.aDouble, 1.0); + expect(complexObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.anObject.aString, "Blah, blah, blah."); + expect(complexObject.anObject.anInt, 1); + expect(complexObject.anObject.aDouble, 1.0); + expect(complexObject.anObject.aListOfStrings, ['one', 'two', 'three']); + expect(complexObject.anObject.aListOfInts, [1, 2, 3]); + expect(complexObject.anObject.aListOfDoubles, [1.0, 2.0, 3.0]); + expect(complexObject.aListOfObjects.length, 3); + + for (int i = 0; i < 3; i++) { + expect(complexObject.aListOfObjects[i].aString, "Blah, blah, blah."); + expect(complexObject.aListOfObjects[i].anInt, i + 1); + expect(complexObject.aListOfObjects[i].aDouble, 1.0); + expect(complexObject.aListOfObjects[i].aListOfStrings, + ['one', 'two', 'three']); + expect(complexObject.aListOfObjects[i].aListOfInts, [1, 2, 3]); + expect(complexObject.aListOfObjects[i].aListOfDoubles, [1.0, 2.0, 3.0]); + } + }); + }); +} diff --git a/jsonexample/test/main_test.dart b/jsonexample/test/main_test.dart deleted file mode 100644 index 0fc93b3bef7..00000000000 --- a/jsonexample/test/main_test.dart +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter_test/flutter_test.dart'; - -void main() { - test('This test always passes.', () {}); -} diff --git a/jsonexample/test/simple_object_unit_test.dart b/jsonexample/test/simple_object_unit_test.dart new file mode 100644 index 00000000000..9a19f813fce --- /dev/null +++ b/jsonexample/test/simple_object_unit_test.dart @@ -0,0 +1,197 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:jsonexample/built_value/built_simple_object.dart'; +import 'package:jsonexample/built_value/built_value_serializers.dart'; +import 'package:jsonexample/dart_convert/converted_simple_object.dart'; +import 'package:jsonexample/json_serializable/serializable_simple_object.dart'; + +void main() { + const typicalObjectJson = { + 'aString': 'Blah, blah, blah.', + 'anInt': 1, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0] + }; + + const emptyListJson = { + 'aString': 'Blah, blah, blah.', + 'anInt': 1, + 'aDouble': 1.0, + 'aListOfStrings': [], + 'aListOfInts': [], + 'aListOfDoubles': [] + }; + + const unexpectedPropertiesJson = { + 'aString': 'Blah, blah, blah.', + 'anInt': 1, + 'aDouble': 1.0, + 'aListOfStrings': ['one', 'two', 'three'], + 'aListOfInts': [1, 2, 3], + 'aListOfDoubles': [1.0, 2.0, 3.0], + 'unexpectedProperty': 'Whoops!' + }; + + const emptyJson = {}; + + group('ConvertedSimpleObject unit tests', () { + test('Typical object is converted correctly', () { + final simpleObject = ConvertedSimpleObject.fromJson(typicalObjectJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, "Blah, blah, blah."); + expect(simpleObject.anInt, 1); + expect(simpleObject.aDouble, 1.0); + expect(simpleObject.aListOfStrings, ['one', 'two', 'three']); + expect(simpleObject.aListOfInts, [1, 2, 3]); + expect(simpleObject.aListOfDoubles, [1.0, 2.0, 3.0]); + }); + + test('Empty object', () { + final simpleObject = ConvertedSimpleObject.fromJson(emptyJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, isNull); + expect(simpleObject.anInt, isNull); + expect(simpleObject.aDouble, isNull); + expect(simpleObject.aListOfStrings, isNull); + expect(simpleObject.aListOfInts, isNull); + expect(simpleObject.aListOfDoubles, isNull); + }); + + test('Empty lists', () { + final simpleObject = ConvertedSimpleObject.fromJson(emptyListJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, "Blah, blah, blah."); + expect(simpleObject.anInt, 1); + expect(simpleObject.aDouble, 1.0); + expect(simpleObject.aListOfStrings, []); + expect(simpleObject.aListOfInts, []); + expect(simpleObject.aListOfDoubles, []); + }); + + test('Extra properties', () { + final simpleObject = + ConvertedSimpleObject.fromJson(unexpectedPropertiesJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, "Blah, blah, blah."); + expect(simpleObject.anInt, 1); + expect(simpleObject.aDouble, 1.0); + expect(simpleObject.aListOfStrings, ['one', 'two', 'three']); + expect(simpleObject.aListOfInts, [1, 2, 3]); + expect(simpleObject.aListOfDoubles, [1.0, 2.0, 3.0]); + }); + }); + + group('SerializableSimpleObject unit tests', () { + test('Typical object is converted correctly', () { + final simpleObject = SerializableSimpleObject.fromJson(typicalObjectJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, "Blah, blah, blah."); + expect(simpleObject.anInt, 1); + expect(simpleObject.aDouble, 1.0); + expect(simpleObject.aListOfStrings, ['one', 'two', 'three']); + expect(simpleObject.aListOfInts, [1, 2, 3]); + expect(simpleObject.aListOfDoubles, [1.0, 2.0, 3.0]); + }); + + test('Empty object results in null fields', () { + final simpleObject = SerializableSimpleObject.fromJson(emptyJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, isNull); + expect(simpleObject.anInt, isNull); + expect(simpleObject.aDouble, isNull); + expect(simpleObject.aListOfStrings, isNull); + expect(simpleObject.aListOfInts, isNull); + expect(simpleObject.aListOfDoubles, isNull); + }); + + test('Empty lists are converted as empty lists', () { + final simpleObject = SerializableSimpleObject.fromJson(emptyListJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, "Blah, blah, blah."); + expect(simpleObject.anInt, 1); + expect(simpleObject.aDouble, 1.0); + expect(simpleObject.aListOfStrings, []); + expect(simpleObject.aListOfInts, []); + expect(simpleObject.aListOfDoubles, []); + }); + + test('Unexpected properties are ignored', () { + final simpleObject = + SerializableSimpleObject.fromJson(unexpectedPropertiesJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, "Blah, blah, blah."); + expect(simpleObject.anInt, 1); + expect(simpleObject.aDouble, 1.0); + expect(simpleObject.aListOfStrings, ['one', 'two', 'three']); + expect(simpleObject.aListOfInts, [1, 2, 3]); + expect(simpleObject.aListOfDoubles, [1.0, 2.0, 3.0]); + }); + }); + + group('BuiltSimpleObject unit tests', () { + test('Typical object is converted correctly', () { + final simpleObject = serializers.deserializeWith( + BuiltSimpleObject.serializer, typicalObjectJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, "Blah, blah, blah."); + expect(simpleObject.anInt, 1); + expect(simpleObject.aDouble, 1.0); + expect(simpleObject.aListOfStrings, ['one', 'two', 'three']); + expect(simpleObject.aListOfInts, [1, 2, 3]); + expect(simpleObject.aListOfDoubles, [1.0, 2.0, 3.0]); + }); + + test('Empty object results in null fields', () { + final simpleObject = + serializers.deserializeWith(BuiltSimpleObject.serializer, emptyJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, isNull); + expect(simpleObject.anInt, isNull); + expect(simpleObject.aDouble, isNull); + expect(simpleObject.aListOfStrings, isNull); + expect(simpleObject.aListOfInts, isNull); + expect(simpleObject.aListOfDoubles, isNull); + }); + + test('Empty lists are converted as empty lists', () { + final simpleObject = serializers.deserializeWith( + BuiltSimpleObject.serializer, emptyListJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, "Blah, blah, blah."); + expect(simpleObject.anInt, 1); + expect(simpleObject.aDouble, 1.0); + expect(simpleObject.aListOfStrings, []); + expect(simpleObject.aListOfInts, []); + expect(simpleObject.aListOfDoubles, []); + }); + + test('Unexpected properties are ignored', () { + final simpleObject = serializers.deserializeWith( + BuiltSimpleObject.serializer, unexpectedPropertiesJson); + + expect(simpleObject, isNotNull); + expect(simpleObject.aString, "Blah, blah, blah."); + expect(simpleObject.anInt, 1); + expect(simpleObject.aDouble, 1.0); + expect(simpleObject.aListOfStrings, ['one', 'two', 'three']); + expect(simpleObject.aListOfInts, [1, 2, 3]); + expect(simpleObject.aListOfDoubles, [1.0, 2.0, 3.0]); + }); + }); +} diff --git a/jsonexample/test/widget_tests_test.dart b/jsonexample/test/widget_tests_test.dart new file mode 100644 index 00000000000..6b1e3f87ee2 --- /dev/null +++ b/jsonexample/test/widget_tests_test.dart @@ -0,0 +1,199 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:jsonexample/dart_convert/converted_simple_object.dart'; +import 'package:jsonexample/dart_convert/converted_complex_object.dart'; +import 'package:jsonexample/widgets.dart'; + +void main() { + group('SimpleObjectView widget test', () { + testWidgets('Typical object is displayed correctly', + (WidgetTester tester) async { + final simpleObject = ConvertedSimpleObject( + aString: 'Blah, blah, blah', + anInt: 1, + aDouble: 1.0, + aListOfStrings: ['one', 'two', 'three'], + aListOfInts: [1, 2, 3], + aListOfDoubles: [1.0, 2.0, 3.0], + ); + + await tester.pumpWidget( + MaterialApp( + home: SimpleObjectView(simpleObject), + ), + ); + + expect(find.text('"Blah, blah, blah"'), findsOneWidget); + expect(find.text('1'), findsOneWidget); + expect(find.text('1.0'), findsOneWidget); + expect(find.text('["one", "two", "three"]'), findsOneWidget); + expect(find.text('[1, 2, 3]'), findsOneWidget); + expect(find.text('[1.0, 2.0, 3.0]'), findsOneWidget); + }); + + testWidgets('Empty lists are displayed as brackets', + (WidgetTester tester) async { + final simpleObject = ConvertedSimpleObject( + aString: 'Blah, blah, blah', + anInt: 1, + aDouble: 1.0, + aListOfStrings: [], + aListOfInts: [], + aListOfDoubles: [], + ); + + await tester.pumpWidget( + MaterialApp( + home: SimpleObjectView(simpleObject), + ), + ); + + expect(find.text('[]'), findsNWidgets(3)); + }); + + testWidgets('Null values are displayed as NULL', + (WidgetTester tester) async { + final simpleObject = ConvertedSimpleObject( + aString: null, + anInt: null, + aDouble: null, + aListOfStrings: null, + aListOfInts: null, + aListOfDoubles: null, + ); + + await tester.pumpWidget( + MaterialApp( + home: SimpleObjectView(simpleObject), + ), + ); + + expect(find.text('NULL'), findsNWidgets(6)); + }); + }); + + group('ComplexObjectView widget test', () { + testWidgets('Typical object is displayed correctly', + (WidgetTester tester) async { + final complexObject = ConvertedComplexObject( + aString: 'Blah, blah, blah', + anInt: 1, + aDouble: 1.0, + aListOfStrings: ['one', 'two', 'three'], + aListOfInts: [1, 2, 3], + aListOfDoubles: [1.0, 2.0, 3.0], + anObject: ConvertedSimpleObject( + aString: "Child 1", + anInt: 101, + aDouble: 101.0, + aListOfStrings: ['1011', '1012', '1013'], + aListOfInts: [1011, 1012, 1013], + aListOfDoubles: [1011.0, 1012.0, 1013.0], + ), + aListOfObjects: [ + ConvertedSimpleObject( + aString: "Child 2", + anInt: 102, + aDouble: 102.0, + aListOfStrings: ['1021', '1022', '1023'], + aListOfInts: [1021, 1022, 1023], + aListOfDoubles: [1021.0, 1022.0, 1023.0], + ), + ConvertedSimpleObject( + aString: "Child 3", + anInt: 103, + aDouble: 103.0, + aListOfStrings: ['1031', '1032', '1033'], + aListOfInts: [1031, 1032, 1033], + aListOfDoubles: [1031.0, 1032.0, 1033.0], + ), + ConvertedSimpleObject( + aString: "Child 4", + anInt: 104, + aDouble: 104.0, + aListOfStrings: ['1041', '1042', '1043'], + aListOfInts: [1041, 1042, 1043], + aListOfDoubles: [1041.0, 1042.0, 1043.0], + ), + ], + ); + + await tester.pumpWidget( + MaterialApp( + home: ComplexObjectView(complexObject), + ), + ); + + expect(find.text('"Blah, blah, blah"'), findsOneWidget); + expect(find.text('1'), findsOneWidget); + expect(find.text('1.0'), findsOneWidget); + expect(find.text('["one", "two", "three"]'), findsOneWidget); + expect(find.text('[1, 2, 3]'), findsOneWidget); + expect(find.text('[1.0, 2.0, 3.0]'), findsOneWidget); + + for (int i = 1; i <= 4; i++) { + expect(find.text('"Child $i"'), findsOneWidget); + expect(find.text('10$i'), findsOneWidget); + expect(find.text('10$i.0'), findsOneWidget); + expect(find.text('["10${i}1", "10${i}2", "10${i}3"]'), findsOneWidget); + expect(find.text('[10${i}1, 10${i}2, 10${i}3]'), findsOneWidget); + expect(find.text('[10${i}1.0, 10${i}2.0, 10${i}3.0]'), findsOneWidget); + } + }); + + testWidgets('Empty lists are displayed as brackets', + (WidgetTester tester) async { + final complexObject = ConvertedComplexObject( + aString: 'Blah, blah, blah', + anInt: 1, + aDouble: 1.0, + aListOfStrings: [], + aListOfInts: [], + aListOfDoubles: [], + anObject: ConvertedSimpleObject( + aString: "Child 1", + anInt: 101, + aDouble: 101.0, + aListOfStrings: ['1011', '1012', '1013'], + aListOfInts: [1011, 1012, 1013], + aListOfDoubles: [1011.0, 1012.0, 1013.0], + ), + aListOfObjects: [], + ); + + await tester.pumpWidget( + MaterialApp( + home: ComplexObjectView(complexObject), + ), + ); + + expect(find.text('[]'), findsNWidgets(4)); + }); + + testWidgets('Null values are displayed as NULL', + (WidgetTester tester) async { + final complexObject = ConvertedComplexObject( + aString: null, + anInt: null, + aDouble: null, + aListOfStrings: null, + aListOfInts: null, + aListOfDoubles: null, + anObject: null, + aListOfObjects: null, + ); + + await tester.pumpWidget( + MaterialApp( + home: ComplexObjectView(complexObject), + ), + ); + + expect(find.text('NULL'), findsNWidgets(8)); + }); + }); +}