diff --git a/CHANGELOG.md b/CHANGELOG.md index 56236f4a..fab381c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 8.12.8-wip + +- Support generating from classes and enums that use the `new` syntax for + constructors. + # 8.12.7 - Allow `analyzer 13.0.0` and `analyzer 14.0.0` diff --git a/built_value_generator/lib/src/enum_source_class.dart b/built_value_generator/lib/src/enum_source_class.dart index 43239bdf..be766fe8 100644 --- a/built_value_generator/lib/src/enum_source_class.dart +++ b/built_value_generator/lib/src/enum_source_class.dart @@ -179,11 +179,15 @@ abstract class EnumSourceClass 'const ${RegExp.escape(name)}._\\((?:final )?String name\\) : super\\(name\\);', ); var expectedCode217 = RegExp( - 'const ${RegExp.escape(name)}._\\(super.name\\);', + 'const (?:${RegExp.escape(name)}\\.|new )_\\(super\\.name\\);', + ); + var expectedCodeNew = RegExp( + 'const new _\\((?:final )?String name\\) : super\\(name\\);', ); return constructors.length == 1 && (constructors.single.contains(expectedCode) || - constructors.single.contains(expectedCode217)) + constructors.single.contains(expectedCode217) || + constructors.single.contains(expectedCodeNew)) ? [] : [ 'Have exactly one constructor: ' diff --git a/built_value_generator/lib/src/value_source_class.dart b/built_value_generator/lib/src/value_source_class.dart index bc187535..1d84f310 100644 --- a/built_value_generator/lib/src/value_source_class.dart +++ b/built_value_generator/lib/src/value_source_class.dart @@ -286,8 +286,7 @@ abstract class ValueSourceClass } @memoized - BuiltList get valueClassConstructors => - BuiltList( + BuiltList get valueClassConstructors => BuiltList( element.constructors .where( (constructor) => @@ -296,17 +295,16 @@ abstract class ValueSourceClass .map( (constructor) => parsedLibrary .getFragmentDeclaration(constructor.firstFragment)! - .node as ConstructorDeclaration, + .node, ), ); @memoized - BuiltList get valueClassFactories => - BuiltList( + BuiltList get valueClassFactories => BuiltList( element.constructors.where((constructor) => constructor.isFactory).map( (factory) => parsedLibrary .getFragmentDeclaration(factory.firstFragment)! - .node as ConstructorDeclaration, + .node, ), ); @@ -314,7 +312,7 @@ abstract class ValueSourceClass bool get builderClassIsAbstract => builderElement!.isAbstract; @memoized - BuiltList get builderClassConstructors => BuiltList( + BuiltList get builderClassConstructors => BuiltList( builderElement!.constructors .where( (constructor) => @@ -323,8 +321,7 @@ abstract class ValueSourceClass .map( (constructor) => parsedLibrary .getFragmentDeclaration(constructor.firstFragment)! - .node - .toSource(), + .node, ), ); @@ -669,6 +666,14 @@ abstract class ValueSourceClass } final expectedConstructor = '$name._()'; + bool constructorCheck(AstNode c) { + if (c is! ConstructorDeclaration) return false; + if (c.name?.lexeme != '_') return false; + if (c.parameters.parameters.isNotEmpty) return false; + if (c.typeName != null && c.typeName!.toSource() != name) return false; + return true; + } + if (valueClassConstructors.isEmpty) { result.add( GeneratorError( @@ -683,7 +688,7 @@ abstract class ValueSourceClass } else if (valueClassConstructors.length > 1) { var found = false; for (var constructor in valueClassConstructors) { - if (constructor.toSource().contains(expectedConstructor)) { + if (constructorCheck(constructor)) { found = true; } else { result.add( @@ -709,14 +714,18 @@ abstract class ValueSourceClass ), ); } - } else if (!(valueClassConstructors.single.toSource().contains( - expectedConstructor, - ))) { + } else if (!constructorCheck(valueClassConstructors.single)) { + final isExactPrimary = valueClassConstructors.single + is! ConstructorDeclaration && + (valueClassConstructors.single.toSource() == expectedConstructor || + valueClassConstructors.single.toSource() == '._()' || + valueClassConstructors.single.toSource() == '_()'); result.add( GeneratorError( (b) => b - ..message = - 'Make class have exactly one constructor: $expectedConstructor' + ..message = isExactPrimary + ? '$expectedConstructor must go in the body.' + : 'Make class have exactly one constructor: $expectedConstructor' ..offset = valueClassConstructors.single.offset ..length = valueClassConstructors.single.length ..fix = expectedConstructor + ';', @@ -816,8 +825,33 @@ abstract class ValueSourceClass if (settings.instantiable) { final expectedConstructor = '${name}Builder._()'; - if (builderClassConstructors.length != 1 || - !(builderClassConstructors.single.contains(expectedConstructor))) { + bool builderConstructorCheck(AstNode c) { + if (c is! ConstructorDeclaration) return false; + if (c.name?.lexeme != '_') return false; + if (c.parameters.parameters.isNotEmpty) return false; + if (c.typeName != null && c.typeName!.toSource() != '${name}Builder') { + return false; + } + return true; + } + + if (builderClassConstructors.length == 1 && + !builderConstructorCheck(builderClassConstructors.single)) { + final isExactPrimary = + builderClassConstructors.single is! ConstructorDeclaration && + (builderClassConstructors.single.toSource() == + expectedConstructor || + builderClassConstructors.single.toSource() == '._()' || + builderClassConstructors.single.toSource() == '_()'); + result.add( + GeneratorError( + (b) => b + ..message = isExactPrimary + ? '$expectedConstructor must go in the body.' + : 'Make builder class have exactly one constructor: $expectedConstructor;', + ), + ); + } else if (builderClassConstructors.length != 1) { result.add( GeneratorError( (b) => b @@ -841,8 +875,11 @@ abstract class ValueSourceClass if (settings.instantiable) { final expectedFactory = 'factory ${name}Builder() = ${implName}Builder$_generics;'; + final expectedFactoryNew = + 'factory ${name}Builder.new() = ${implName}Builder$_generics;'; if (builderClassFactories.length != 1 || - !builderClassFactories.single.contains(expectedFactory)) { + (!builderClassFactories.single.contains(expectedFactory) && + !builderClassFactories.single.contains(expectedFactoryNew))) { result.add( GeneratorError( (b) => b diff --git a/built_value_generator/lib/src/value_source_class.g.dart b/built_value_generator/lib/src/value_source_class.g.dart index 38a2547b..44611ba9 100644 --- a/built_value_generator/lib/src/value_source_class.g.dart +++ b/built_value_generator/lib/src/value_source_class.g.dart @@ -38,10 +38,10 @@ class _$ValueSourceClass extends ValueSourceClass { bool? __hasBuiltValueImportWithShow; bool? __hasBuiltValueImportWithAs; bool? __valueClassIsAbstract; - BuiltList? __valueClassConstructors; - BuiltList? __valueClassFactories; + BuiltList? __valueClassConstructors; + BuiltList? __valueClassFactories; bool? __builderClassIsAbstract; - BuiltList? __builderClassConstructors; + BuiltList? __builderClassConstructors; BuiltList? __builderClassFactories; BuiltList? __memoizedGetters; BuiltList? __builderImplements; @@ -160,11 +160,11 @@ class _$ValueSourceClass extends ValueSourceClass { __valueClassIsAbstract ??= super.valueClassIsAbstract; @override - BuiltList get valueClassConstructors => + BuiltList get valueClassConstructors => __valueClassConstructors ??= super.valueClassConstructors; @override - BuiltList get valueClassFactories => + BuiltList get valueClassFactories => __valueClassFactories ??= super.valueClassFactories; @override @@ -172,7 +172,7 @@ class _$ValueSourceClass extends ValueSourceClass { __builderClassIsAbstract ??= super.builderClassIsAbstract; @override - BuiltList get builderClassConstructors => + BuiltList get builderClassConstructors => __builderClassConstructors ??= super.builderClassConstructors; @override diff --git a/built_value_generator/test/built_value_generator_test.dart b/built_value_generator/test/built_value_generator_test.dart index a77278c2..890e2f27 100644 --- a/built_value_generator/test/built_value_generator_test.dart +++ b/built_value_generator/test/built_value_generator_test.dart @@ -471,6 +471,103 @@ abstract class ValueBuilder implements Builder { }'''), contains('1. Make class have exactly one constructor: Value._();')); }); + test('to fix invalid primary constructor on value class', () async { + expect(await generate('''library value; +import 'package:built_value/built_value.dart'; +part 'value.g.dart'; +abstract class Value.other() implements Built { + factory Value([void Function(ValueBuilder) updates]) = _\$Value; +} +abstract class ValueBuilder implements Builder { + ValueBuilder._(); + factory ValueBuilder() = _\$ValueBuilder; +}'''), contains('1. Make class have exactly one constructor: Value._()')); + }); + + test('to reject exact Value._() primary constructor', () async { + final result = await generate('''library value; +import 'package:built_value/built_value.dart'; +part 'value.g.dart'; +abstract class Value._() implements Built { + factory Value([void Function(ValueBuilder) updates]) = _\$Value; +} +abstract class ValueBuilder implements Builder { + ValueBuilder._(); + factory ValueBuilder() = _\$ValueBuilder; +}'''); + expect(result, contains('1. Value._() must go in the body.')); + }); + + test('to reject exact ValueBuilder._() primary constructor', () async { + final result = await generate('''library value; +import 'package:built_value/built_value.dart'; +part 'value.g.dart'; +abstract class Value implements Built { + Value._(); + factory Value([void Function(ValueBuilder) updates]) = _\$Value; +} +abstract class ValueBuilder._() implements Builder { + factory ValueBuilder() = _\$ValueBuilder; +}'''); + expect(result, contains('1. ValueBuilder._() must go in the body.')); + }); + + test('to fix primary constructor with parameters on value class', + () async { + expect(await generate('''library value; +import 'package:built_value/built_value.dart'; +part 'value.g.dart'; +abstract class Value._(int x) implements Built { + factory Value([void Function(ValueBuilder) updates]) = _\$Value; +} +abstract class ValueBuilder implements Builder { + ValueBuilder._(); + factory ValueBuilder() = _\$ValueBuilder; +}'''), contains('1. Make class have exactly one constructor: Value._()')); + }); + + test('to fix new constructor with parameters on value class', () async { + expect(await generate('''library value; +import 'package:built_value/built_value.dart'; +part 'value.g.dart'; +abstract class Value implements Built { + new _(int x); + factory Value([void Function(ValueBuilder) updates]) = _\$Value; +} +abstract class ValueBuilder implements Builder { + ValueBuilder._(); + factory ValueBuilder() = _\$ValueBuilder; +}'''), contains('1. Make class have exactly one constructor: Value._()')); + }); + + test('to remove primary constructor from non-instantiable value class', + () async { + expect(await generate('''library value; +import 'package:built_value/built_value.dart'; +part 'value.g.dart'; +@BuiltValue(instantiable: false) +abstract class Value._() implements Built { +} +abstract class ValueBuilder implements Builder { +}'''), contains('1. Remove all constructors or remove "instantiable: false".')); + }); + + test( + 'to remove extra constructor when value class has primary constructor', + () async { + expect(await generate('''library value; +import 'package:built_value/built_value.dart'; +part 'value.g.dart'; +abstract class Value._() implements Built { + Value.other(); + factory Value([void Function(ValueBuilder) updates]) = _\$Value; +} +abstract class ValueBuilder implements Builder { + ValueBuilder._(); + factory ValueBuilder() = _\$ValueBuilder; +}'''), contains('1. Remove invalid constructor.')); + }); + test('to add constructor when there is synthetic constructor', () async { expect(await generate('''library value; import 'package:built_value/built_value.dart'; @@ -578,6 +675,56 @@ abstract class ValueBuilder implements Builder { 'have exactly one constructor: ValueBuilder._();')); }); + test('to fix invalid primary constructor on builder class', () async { + expect( + await generate('''library value; +import 'package:built_value/built_value.dart'; +part 'value.g.dart'; +abstract class Value implements Built { + Value._(); + factory Value([void Function(ValueBuilder) updates]) = _\$Value; +} +abstract class ValueBuilder.other() implements Builder { + factory ValueBuilder() = _\$ValueBuilder; +}'''), + contains('1. Make builder class ' + 'have exactly one constructor: ValueBuilder._();')); + }); + + test('to fix primary constructor with parameters on builder class', + () async { + expect( + await generate('''library value; +import 'package:built_value/built_value.dart'; +part 'value.g.dart'; +abstract class Value implements Built { + Value._(); + factory Value([void Function(ValueBuilder) updates]) = _\$Value; +} +abstract class ValueBuilder._(int x) implements Builder { + factory ValueBuilder() = _\$ValueBuilder; +}'''), + contains('1. Make builder class ' + 'have exactly one constructor: ValueBuilder._();')); + }); + + test('to fix new constructor with parameters on builder class', () async { + expect( + await generate('''library value; +import 'package:built_value/built_value.dart'; +part 'value.g.dart'; +abstract class Value implements Built { + Value._(); + factory Value([void Function(ValueBuilder) updates]) = _\$Value; +} +abstract class ValueBuilder implements Builder { + new _(int x); + factory ValueBuilder() = _\$ValueBuilder; +}'''), + contains('1. Make builder class ' + 'have exactly one constructor: ValueBuilder._();')); + }); + test('constructor for builder class with synthetic constructor', () async { expect( diff --git a/built_value_generator/test/enum_class_generator_test.dart b/built_value_generator/test/enum_class_generator_test.dart index 24fe3dcc..953f4351 100644 --- a/built_value_generator/test/enum_class_generator_test.dart +++ b/built_value_generator/test/enum_class_generator_test.dart @@ -250,6 +250,31 @@ class TestEnum extends EnumClass { '''), contains(r'''Please make the following changes to use EnumClass: +1. Have exactly one constructor: const TestEnum._(String name) : super(name); ''' + 'or in Dart>=2.17: const TestEnum._(super.name);')); + }); + + test('with error on primary constructor for EnumClass', () async { + expect( + await generate(r''' +// @dart=3.14 +library test_enum; + +import 'package:built_value/built_value.dart'; + +part 'test_enum.g.dart'; + +class TestEnum._(super.name) extends EnumClass { + static const TestEnum yes = _$yes; + static const TestEnum no = _$no; + static const TestEnum maybe = _$maybe; + + static BuiltSet get values => _$values; + static TestEnum valueOf(String name) => _$valueOf(name); +} +'''), + contains(r'''Please make the following changes to use EnumClass: + 1. Have exactly one constructor: const TestEnum._(String name) : super(name); ''' 'or in Dart>=2.17: const TestEnum._(super.name);')); }); @@ -418,6 +443,17 @@ class TestEnum extends EnumClass { contains(correctOutput)); }); + test('allows new constructor naming syntax with string parameter', + () async { + expect( + await generate('// @dart=3.14\n' + + correctInput.replaceAll( + 'const TestEnum._(String name) : super(name);', + 'const new _(String name) : super(name);')), + contains(correctOutput.replaceFirst( + 'abstract class _\$TestEnumMixin', 'mixin _\$TestEnumMixin'))); + }); + test('ignores fields of different type', () async { expect( await generate(correctInput.replaceAll( @@ -603,7 +639,8 @@ Builder get builder => PartBuilder([BuiltValueGenerator()], '.g.dart'); Future generate(String source) async { final srcs = { 'built_value|lib/built_value.dart': builtValueSource, - '$pkgName|lib/test_enum.dart': '// @dart=2.19\n$source', + '$pkgName|lib/test_enum.dart': + source.startsWith('// @dart') ? source : '// @dart=2.19\n$source', }; // Capture any error from generation; if there is one, return that instead of diff --git a/end_to_end_test/lib/enums.dart b/end_to_end_test/lib/enums.dart index 522a731f..e0fe31ca 100644 --- a/end_to_end_test/lib/enums.dart +++ b/end_to_end_test/lib/enums.dart @@ -139,3 +139,16 @@ class EnumWith$Dollar_UnderScore extends EnumClass { static EnumWith$Dollar_UnderScore valueOf(String name) => _$enum$Dollar_UnderScoreValueOf(name); } + +class NewConstructorEnum extends EnumClass { + static Serializer get serializer => + _$newConstructorEnumSerializer; + + static const NewConstructorEnum yes = _$newYes; + static const NewConstructorEnum no = _$newNo; + + const new _(super.name); + + static BuiltSet get values => _$newValues; + static NewConstructorEnum valueOf(String name) => _$newValueOf(name); +} diff --git a/end_to_end_test/lib/enums.g.dart b/end_to_end_test/lib/enums.g.dart index 2124ff30..e4ae4e84 100644 --- a/end_to_end_test/lib/enums.g.dart +++ b/end_to_end_test/lib/enums.g.dart @@ -190,6 +190,24 @@ final BuiltSet _$enum$Dollar_UnderScoreValues = _$dollar_UnderScoreEnumValue$, ]); +const NewConstructorEnum _$newYes = const NewConstructorEnum._('yes'); +const NewConstructorEnum _$newNo = const NewConstructorEnum._('no'); + +NewConstructorEnum _$newValueOf(String name) { + switch (name) { + case 'yes': + return _$newYes; + case 'no': + return _$newNo; + default: + throw ArgumentError(name); + } +} + +final BuiltSet _$newValues = BuiltSet( + const [_$newYes, _$newNo], +); + Serializer _$testEnumSerializer = _$TestEnumSerializer(); Serializer _$wireNameEnumSerializer = _$WireNameEnumSerializer(); Serializer _$wireNumberEnumSerializer = @@ -201,6 +219,8 @@ Serializer _$fallbackNumberEnumSerializer = _$FallbackNumberEnumSerializer(); Serializer _$enumWith$DollarUnderScoreSerializer = _$EnumWith$Dollar_UnderScoreSerializer(); +Serializer _$newConstructorEnumSerializer = + _$NewConstructorEnumSerializer(); class _$TestEnumSerializer implements PrimitiveSerializer { @override @@ -410,4 +430,26 @@ class _$EnumWith$Dollar_UnderScoreSerializer ); } +class _$NewConstructorEnumSerializer + implements PrimitiveSerializer { + @override + final Iterable types = const [NewConstructorEnum]; + @override + final String wireName = 'NewConstructorEnum'; + + @override + Object serialize( + Serializers serializers, + NewConstructorEnum object, { + FullType specifiedType = FullType.unspecified, + }) => object.name; + + @override + NewConstructorEnum deserialize( + Serializers serializers, + Object serialized, { + FullType specifiedType = FullType.unspecified, + }) => NewConstructorEnum.valueOf(serialized as String); +} + // ignore_for_file: deprecated_member_use_from_same_package,type=lint diff --git a/end_to_end_test/lib/serializers.dart b/end_to_end_test/lib/serializers.dart index 2f9be095..75f98079 100644 --- a/end_to_end_test/lib/serializers.dart +++ b/end_to_end_test/lib/serializers.dart @@ -48,6 +48,8 @@ part 'serializers.g.dart'; ImportedCustomNestedValue, NamedFactoryValue, NestedGenericContainer, + NewConstructorEnum, + NewConstructorValue, NonBuiltGeneric, OtherValue, PartiallySerializableValue, diff --git a/end_to_end_test/lib/serializers.g.dart b/end_to_end_test/lib/serializers.g.dart index 8cb659be..4b7f4f4b 100644 --- a/end_to_end_test/lib/serializers.g.dart +++ b/end_to_end_test/lib/serializers.g.dart @@ -39,6 +39,8 @@ Serializers _$serializers = ..add(ImportedValue.serializer) ..add(NamedFactoryValue.serializer) ..add(NestedGenericContainer.serializer) + ..add(NewConstructorEnum.serializer) + ..add(NewConstructorValue.serializer) ..add(NoFieldsValue.serializer) ..add(NonBuiltGeneric.serializer) ..add(OtherValue.serializer) diff --git a/end_to_end_test/lib/values.dart b/end_to_end_test/lib/values.dart index 8e9942b4..bca8dbd3 100644 --- a/end_to_end_test/lib/values.dart +++ b/end_to_end_test/lib/values.dart @@ -987,3 +987,26 @@ abstract class VariousFunctionsValue ]) = _$VariousFunctionsValue; VariousFunctionsValue._(); } + +abstract class NewConstructorValue + implements Built { + static Serializer get serializer => + _$newConstructorValueSerializer; + + int get anInt; + + new _(); + + factory NewConstructorValue.new([ + void Function(NewConstructorValueBuilder) updates, + ]) = _$NewConstructorValue; +} + +abstract class NewConstructorValueBuilder + implements Builder { + int? anInt; + + new _(); + + factory NewConstructorValueBuilder.new() = _$NewConstructorValueBuilder; +} diff --git a/end_to_end_test/lib/values.g.dart b/end_to_end_test/lib/values.g.dart index 3a657dfa..8c3ff853 100644 --- a/end_to_end_test/lib/values.g.dart +++ b/end_to_end_test/lib/values.g.dart @@ -76,6 +76,8 @@ Serializer<$ValueSpecial> _$$valueSpecialSerializer = Serializer _$valueWithAwkwardNestedBuilderSerializer = _$ValueWithAwkwardNestedBuilderSerializer(); +Serializer _$newConstructorValueSerializer = + _$NewConstructorValueSerializer(); class _$SimpleValueSerializer implements StructuredSerializer { @override @@ -2491,6 +2493,59 @@ class _$ValueWithAwkwardNestedBuilderSerializer } } +class _$NewConstructorValueSerializer + implements StructuredSerializer { + @override + final Iterable types = const [ + NewConstructorValue, + _$NewConstructorValue, + ]; + @override + final String wireName = 'NewConstructorValue'; + + @override + Iterable serialize( + Serializers serializers, + NewConstructorValue object, { + FullType specifiedType = FullType.unspecified, + }) { + final result = [ + 'anInt', + serializers.serialize(object.anInt, specifiedType: const FullType(int)), + ]; + + return result; + } + + @override + NewConstructorValue deserialize( + Serializers serializers, + Iterable serialized, { + FullType specifiedType = FullType.unspecified, + }) { + final result = NewConstructorValueBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current! as String; + iterator.moveNext(); + final Object? value = iterator.current; + switch (key) { + case 'anInt': + result.anInt = + serializers.deserialize( + value, + specifiedType: const FullType(int), + )! + as int; + break; + } + } + + return result.build(); + } +} + class _$SimpleValue extends SimpleValue { @override final int anInt; @@ -8093,4 +8148,100 @@ class VariousFunctionsValueBuilder } } +class _$NewConstructorValue extends NewConstructorValue { + @override + final int anInt; + + factory _$NewConstructorValue([ + void Function(NewConstructorValueBuilder)? updates, + ]) => + (NewConstructorValueBuilder()..update(updates)).build() + as _$NewConstructorValue; + + _$NewConstructorValue._({required this.anInt}) : super._(); + @override + NewConstructorValue rebuild( + void Function(NewConstructorValueBuilder) updates, + ) => (toBuilder()..update(updates)).build(); + + @override + _$NewConstructorValueBuilder toBuilder() => + _$NewConstructorValueBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is NewConstructorValue && anInt == other.anInt; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, anInt.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } + + @override + String toString() { + return (newBuiltValueToStringHelper( + r'NewConstructorValue', + )..add('anInt', anInt)).toString(); + } +} + +class _$NewConstructorValueBuilder extends NewConstructorValueBuilder { + _$NewConstructorValue? _$v; + + @override + int? get anInt { + _$this; + return super.anInt; + } + + @override + set anInt(int? anInt) { + _$this; + super.anInt = anInt; + } + + _$NewConstructorValueBuilder() : super._(); + + NewConstructorValueBuilder get _$this { + final $v = _$v; + if ($v != null) { + super.anInt = $v.anInt; + _$v = null; + } + return this; + } + + @override + void replace(NewConstructorValue other) { + _$v = other as _$NewConstructorValue; + } + + @override + void update(void Function(NewConstructorValueBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + NewConstructorValue build() => _build(); + + _$NewConstructorValue _build() { + final _$result = + _$v ?? + _$NewConstructorValue._( + anInt: BuiltValueNullFieldError.checkNotNull( + anInt, + r'NewConstructorValue', + 'anInt', + ), + ); + replace(_$result); + return _$result; + } +} + // ignore_for_file: deprecated_member_use_from_same_package,type=lint diff --git a/end_to_end_test/test/enums_serializer_test.dart b/end_to_end_test/test/enums_serializer_test.dart index 555dc005..c5d17d59 100644 --- a/end_to_end_test/test/enums_serializer_test.dart +++ b/end_to_end_test/test/enums_serializer_test.dart @@ -23,6 +23,20 @@ void main() { }); }); + group('NewConstructorEnum', () { + var data = NewConstructorEnum.yes; + var serialized = + json.decode(json.encode(['NewConstructorEnum', 'yes'])) as Object; + + test('can be serialized', () { + expect(serializers.serialize(data), serialized); + }); + + test('can be deserialized', () { + expect(serializers.deserialize(serialized), data); + }); + }); + group('WireNameEnum', () { var data = WireNameEnum.yes; var serialized = json.decode(json.encode(['E', 'y'])) as Object; diff --git a/end_to_end_test/test/enums_test.dart b/end_to_end_test/test/enums_test.dart index d31648ea..2fd238bd 100644 --- a/end_to_end_test/test/enums_test.dart +++ b/end_to_end_test/test/enums_test.dart @@ -22,6 +22,14 @@ void main() { FallbackEnum.no); }); }); + group(NewConstructorEnum, () { + test('values and valueOf work as expected', () { + expect(NewConstructorEnum.values, + [NewConstructorEnum.yes, NewConstructorEnum.no]); + expect(NewConstructorEnum.valueOf('yes'), NewConstructorEnum.yes); + expect(NewConstructorEnum.valueOf('no'), NewConstructorEnum.no); + }); + }); } class UsesTestEnumMixin with TestEnumMixin { diff --git a/end_to_end_test/test/values_serializer_test.dart b/end_to_end_test/test/values_serializer_test.dart index 8fc030a2..00698e63 100644 --- a/end_to_end_test/test/values_serializer_test.dart +++ b/end_to_end_test/test/values_serializer_test.dart @@ -700,4 +700,21 @@ void main() { expect(serializers.deserialize(serialized), data); }); }); + + group('NewConstructorValue', () { + var data = NewConstructorValue((b) => b..anInt = 1); + var serialized = json.decode(json.encode([ + 'NewConstructorValue', + 'anInt', + 1, + ])) as Object; + + test('can be serialized', () { + expect(serializers.serialize(data), serialized); + }); + + test('can be deserialized', () { + expect(serializers.deserialize(serialized), data); + }); + }); } diff --git a/end_to_end_test/test/values_test.dart b/end_to_end_test/test/values_test.dart index 990d3017..89b7f492 100644 --- a/end_to_end_test/test/values_test.dart +++ b/end_to_end_test/test/values_test.dart @@ -506,4 +506,12 @@ void main() { ]); }); }); + + group('NewConstructorValue', () { + test('has correct field name and type with new _()', () { + final value = NewConstructorValue((b) => b..anInt = 42); + expect(value.anInt, 42); + expect(value.anInt, isA()); + }); + }); }