Skip to content

Commit 54490fa

Browse files
committed
test: add tests for new features
1 parent 72cc27c commit 54490fa

9 files changed

+1424
-10
lines changed

json_serializable/lib/src/generator_helper.dart

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,12 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper {
5959
),
6060
);
6161

62-
if (sealedSupersAndConfigs.isNotEmpty &&
63-
sealedSupersAndConfigs.any((e) => e.config == null)) {
62+
if (sealedSupersAndConfigs.firstWhereOrNull((e) => e.config == null)
63+
case final notAnnotated? when sealedSupersAndConfigs.isNotEmpty) {
6464
throw InvalidGenerationSourceError(
6565
'The class `${element.displayName}` is annotated '
66-
'with `JsonSerializable` but its superclass is not annotated '
66+
'with `JsonSerializable` but its sealed superclass '
67+
'`${notAnnotated.classElement.displayName}` is not annotated '
6768
'with `JsonSerializable`.',
6869
todo: 'Add `@JsonSerializable` annotation to the sealed class.',
6970
element: element,
@@ -89,10 +90,11 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper {
8990
case final conflictingSuper? when element.isSealed) {
9091
throw InvalidGenerationSource(
9192
'The classes `${conflictingSuper.classElement.displayName}` and '
92-
'${element.displayName} are nested sealed classes, but they have '
93-
'the same discriminator ${config.unionDiscriminator}.',
93+
'`${element.displayName}` are nested sealed classes, but they have '
94+
'the same discriminator `${config.unionDiscriminator}`.',
9495
todo: 'Rename one of the discriminators with `unionDiscriminator` '
9596
'field of `@JsonSerializable`.',
97+
element: element,
9698
);
9799
}
98100

@@ -192,11 +194,12 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper {
192194
(Set<String> set, fe) {
193195
final jsonKey = nameAccess(fe);
194196

195-
if (sealedSupersAndConfigs
196-
.any((e) => e.config?.unionDiscriminator == jsonKey)) {
197+
if (sealedSupersAndConfigs.firstWhereOrNull(
198+
(e) => e.config?.unionDiscriminator == jsonKey)
199+
case final conflict?) {
197200
throw InvalidGenerationSourceError(
198-
'The JSON key "$jsonKey" is conflicting with the discriminator '
199-
'of sealed superclass ',
201+
'The JSON key `$jsonKey` is conflicting with the discriminator '
202+
'of sealed superclass `${conflict.classElement.displayName}`',
200203
todo: 'Rename the field or the discriminator.',
201204
element: fe,
202205
);

json_serializable/test/json_serializable_test.dart

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,72 @@ const _expectedAnnotatedTests = {
122122
'Reproduce869NullableGenericTypeWithDefault',
123123
'SameCtorAndJsonKeyDefaultValue',
124124
'SetSupport',
125+
'SubFourMultipleImpl',
126+
'SubNestedOneOne',
127+
'SubNestedOneTwo',
128+
'SubNestedTwoOne',
129+
'SubNestedTwoTwo',
130+
'SubOneMultipleImpl',
131+
'SubOneSimpleSealedClass',
132+
'SubOneSimpleSealedClassWithChangedDiscriminator',
133+
'SubOneSimpleSealedClassWithChangedDiscriminatorAndUnionRename',
134+
'SubOneSimpleSealedClassWithChangedUnionRename',
135+
'SubSimpleSealedClassWithoutToJson',
136+
'SubThreeMultipleImpl',
137+
'SubTwoMultipleImpl',
138+
'SubTwoSimpleSealedClass',
139+
'SubTwoSimpleSealedClassWithChangedDiscriminator',
140+
'SubTwoSimpleSealedClassWithChangedDiscriminatorAndUnionRename',
141+
'SubTwoSimpleSealedClassWithChangedUnionRename',
125142
'SubType',
126143
'SubTypeWithAnnotatedFieldOverrideExtends',
127144
'SubTypeWithAnnotatedFieldOverrideExtendsWithOverrides',
128145
'SubTypeWithAnnotatedFieldOverrideImplements',
146+
'SubUnionRenameKebab',
147+
'SubUnionRenameNone',
148+
'SubUnionRenamePascal',
149+
'SubUnionRenameScreamingSnake',
150+
'SubUnionRenameSnake',
151+
'SubWithConflictingDiscriminatorWithDefaultNameExt',
152+
'SubWithConflictingDiscriminatorWithDefaultNameImpl',
153+
'SubWithConflictingDiscriminatorWithFieldRenameExt',
154+
'SubWithConflictingDiscriminatorWithFieldRenameImpl',
155+
'SubWithConflictingDiscriminatorWithJsonKeyExt',
156+
'SubWithConflictingDiscriminatorWithJsonKeyImpl',
157+
'SubWithSubAndSuperGenericArgumentFactoriesExt',
158+
'SubWithSubAndSuperGenericArgumentFactoriesImpl',
159+
'SubWithSubGenericArgumentFactoriesExt',
160+
'SubWithSubGenericArgumentFactoriesImpl',
161+
'SubWithToJsonAndSuperWithoutToJsonExt',
162+
'SubWithToJsonAndSuperWithoutToJsonImpl',
163+
'SubWithoutSuperJsonSerializableAnnotationExt',
164+
'SubWithoutSuperJsonSerializableAnnotationImpl',
165+
'SubWithoutToJsonAndSuperWithToJsonExt',
166+
'SubWithoutToJsonAndSuperWithToJsonImpl',
129167
'SubclassedJsonKey',
168+
'SuperMultipleImplOne',
169+
'SuperMultipleImplTwo',
170+
'SuperNestedOneOne',
171+
'SuperNestedOneTwo',
172+
'SuperNestedTwoOne',
173+
'SuperNestedTwoTwo',
174+
'SuperSimpleSealedClass',
175+
'SuperSimpleSealedClassWithChangedDiscriminator',
176+
'SuperSimpleSealedClassWithChangedDiscriminatorAndUnionRename',
177+
'SuperSimpleSealedClassWithChangedUnionRename',
178+
'SuperSimpleSealedClassWithoutToJson',
179+
'SuperSuperNestedOne',
180+
'SuperSuperNestedTwo',
181+
'SuperSuperSuperNested',
182+
'SuperUnionRenameKebab',
183+
'SuperUnionRenameNone',
184+
'SuperUnionRenamePascal',
185+
'SuperUnionRenameScreamingSnake',
186+
'SuperUnionRenameSnake',
187+
'SuperWithConflictingNestedDiscriminator',
188+
'SuperWithGenericArgumentFactories',
189+
'SuperWithSubExtWithoutJsonSerializableAnnotation',
190+
'SuperWithSubImplWithoutJsonSerializableAnnotation',
130191
'TearOffFromJsonClass',
131192
'ToJsonNullableFalseIncludeIfNullFalse',
132193
'TypedConvertMethods',
@@ -148,5 +209,5 @@ const _expectedAnnotatedTests = {
148209
'WrongConstructorNameClass',
149210
'_BetterPrivateNames',
150211
'annotatedMethod',
151-
'theAnswer',
212+
'theAnswer'
152213
};

json_serializable/test/src/_json_serializable_test_input.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:json_annotation/json_annotation.dart';
1010
import 'package:source_gen_test/annotations.dart';
1111

1212
part 'checked_test_input.dart';
13+
part 'conflicting_discriminator_input.dart';
1314
part 'constants_copy.dart';
1415
part 'core_subclass_type_input.dart';
1516
part 'default_value_input.dart';
@@ -18,8 +19,12 @@ part 'generic_test_input.dart';
1819
part 'inheritance_test_input.dart';
1920
part 'json_converter_test_input.dart';
2021
part 'map_key_variety_test_input.dart';
22+
part 'mismatching_config_input.dart';
23+
part 'missing_annotation_input.dart';
24+
part 'sealed_test_input.dart';
2125
part 'setter_test_input.dart';
2226
part 'to_from_json_test_input.dart';
27+
part 'union_namer_input.dart';
2328
part 'unknown_enum_value_test_input.dart';
2429

2530
@ShouldThrow('`@JsonSerializable` can only be used on classes.')
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// @dart=3.6
2+
3+
part of '_json_serializable_test_input.dart';
4+
5+
@JsonSerializable(
6+
unionDiscriminator: 'this_will_conflict',
7+
)
8+
sealed class SuperWithConflictingSnakeCaseDiscriminator {}
9+
10+
@ShouldThrow(
11+
'The JSON key `this_will_conflict` is conflicting with the discriminator '
12+
'of sealed superclass `SuperWithConflictingSnakeCaseDiscriminator`',
13+
todo: 'Rename the field or the discriminator.',
14+
element: 'thisWillConflict',
15+
)
16+
@JsonSerializable(
17+
fieldRename: FieldRename.snake,
18+
)
19+
class SubWithConflictingDiscriminatorWithFieldRenameExt
20+
extends SuperWithConflictingSnakeCaseDiscriminator {
21+
final String thisWillConflict;
22+
23+
SubWithConflictingDiscriminatorWithFieldRenameExt({
24+
required this.thisWillConflict,
25+
});
26+
}
27+
28+
@ShouldThrow(
29+
'The JSON key `this_will_conflict` is conflicting with the discriminator '
30+
'of sealed superclass `SuperWithConflictingSnakeCaseDiscriminator`',
31+
todo: 'Rename the field or the discriminator.',
32+
element: 'thisWillConflict',
33+
)
34+
@JsonSerializable(
35+
fieldRename: FieldRename.snake,
36+
)
37+
class SubWithConflictingDiscriminatorWithFieldRenameImpl
38+
implements SuperWithConflictingSnakeCaseDiscriminator {
39+
final String thisWillConflict;
40+
41+
SubWithConflictingDiscriminatorWithFieldRenameImpl({
42+
required this.thisWillConflict,
43+
});
44+
}
45+
46+
@ShouldThrow(
47+
'The JSON key `this_will_conflict` is conflicting with the discriminator '
48+
'of sealed superclass `SuperWithConflictingSnakeCaseDiscriminator`',
49+
todo: 'Rename the field or the discriminator.',
50+
element: 'conflict',
51+
)
52+
@JsonSerializable()
53+
class SubWithConflictingDiscriminatorWithJsonKeyExt
54+
extends SuperWithConflictingSnakeCaseDiscriminator {
55+
@JsonKey(name: 'this_will_conflict')
56+
final String conflict;
57+
58+
SubWithConflictingDiscriminatorWithJsonKeyExt({
59+
required this.conflict,
60+
});
61+
}
62+
63+
@ShouldThrow(
64+
'The JSON key `this_will_conflict` is conflicting with the discriminator '
65+
'of sealed superclass `SuperWithConflictingSnakeCaseDiscriminator`',
66+
todo: 'Rename the field or the discriminator.',
67+
element: 'conflict',
68+
)
69+
@JsonSerializable()
70+
class SubWithConflictingDiscriminatorWithJsonKeyImpl
71+
implements SuperWithConflictingSnakeCaseDiscriminator {
72+
@JsonKey(name: 'this_will_conflict')
73+
final String conflict;
74+
75+
SubWithConflictingDiscriminatorWithJsonKeyImpl({
76+
required this.conflict,
77+
});
78+
}
79+
80+
@JsonSerializable(
81+
unionDiscriminator: 'conflict',
82+
)
83+
sealed class SuperWithConflictingDefaultCaseDiscriminator {}
84+
85+
@ShouldThrow(
86+
'The JSON key `conflict` is conflicting with the discriminator '
87+
'of sealed superclass `SuperWithConflictingDefaultCaseDiscriminator`',
88+
todo: 'Rename the field or the discriminator.',
89+
element: 'conflict',
90+
)
91+
@JsonSerializable()
92+
class SubWithConflictingDiscriminatorWithDefaultNameExt
93+
extends SuperWithConflictingDefaultCaseDiscriminator {
94+
final String conflict;
95+
96+
SubWithConflictingDiscriminatorWithDefaultNameExt({
97+
required this.conflict,
98+
});
99+
}
100+
101+
@ShouldThrow(
102+
'The JSON key `conflict` is conflicting with the discriminator '
103+
'of sealed superclass `SuperWithConflictingDefaultCaseDiscriminator`',
104+
todo: 'Rename the field or the discriminator.',
105+
element: 'conflict',
106+
)
107+
@JsonSerializable()
108+
class SubWithConflictingDiscriminatorWithDefaultNameImpl
109+
extends SuperWithConflictingDefaultCaseDiscriminator {
110+
final String conflict;
111+
112+
SubWithConflictingDiscriminatorWithDefaultNameImpl({
113+
required this.conflict,
114+
});
115+
}
116+
117+
@JsonSerializable(
118+
unionDiscriminator: 'this_will_conflict',
119+
)
120+
sealed class SuperSuperSuperWithConflictingNestedDiscriminator {}
121+
122+
@JsonSerializable(
123+
unionDiscriminator: 'this_is_fine',
124+
)
125+
sealed class SuperSuperWithConflictingNestedDiscriminator
126+
extends SuperSuperSuperWithConflictingNestedDiscriminator {}
127+
128+
@ShouldThrow(
129+
'The classes `SuperSuperSuperWithConflictingNestedDiscriminator` and '
130+
'`SuperWithConflictingNestedDiscriminator` are nested sealed classes, but they have '
131+
'the same discriminator `this_will_conflict`.',
132+
todo: 'Rename one of the discriminators with `unionDiscriminator` '
133+
'field of `@JsonSerializable`.',
134+
element: 'SuperWithConflictingNestedDiscriminator',
135+
)
136+
@JsonSerializable(
137+
unionDiscriminator: 'this_will_conflict',
138+
)
139+
sealed class SuperWithConflictingNestedDiscriminator
140+
extends SuperSuperWithConflictingNestedDiscriminator {}

json_serializable/test/src/generic_test_input.dart

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,82 @@ Map<String, dynamic> _$GenericArgumentFactoriesFlagWithoutGenericTypeToJson(
8585
)
8686
@JsonSerializable(genericArgumentFactories: true)
8787
class GenericArgumentFactoriesFlagWithoutGenericType {}
88+
89+
@ShouldThrow(
90+
'The class `SuperWithGenericArgumentFactories` is annotated '
91+
'with `JsonSerializable` field `genericArgumentFactories: true`. '
92+
'`genericArgumentFactories: true` is not supported for classes '
93+
'that are sealed or have sealed superclasses.',
94+
todo: 'Remove the `genericArgumentFactories` option or '
95+
'remove the `sealed` keyword from the class.',
96+
element: 'SuperWithGenericArgumentFactories',
97+
)
98+
@JsonSerializable(
99+
genericArgumentFactories: true,
100+
)
101+
sealed class SuperWithGenericArgumentFactories<T> {}
102+
103+
@JsonSerializable(
104+
genericArgumentFactories: false,
105+
)
106+
sealed class SuperWithoutGenericArgumentFactories {}
107+
108+
@ShouldThrow(
109+
'The class `SubWithSubGenericArgumentFactoriesExt` is annotated '
110+
'with `JsonSerializable` field `genericArgumentFactories: true`. '
111+
'`genericArgumentFactories: true` is not supported for classes '
112+
'that are sealed or have sealed superclasses.',
113+
todo: 'Remove the `genericArgumentFactories` option or '
114+
'remove the `sealed` keyword from the class.',
115+
element: 'SubWithSubGenericArgumentFactoriesExt',
116+
)
117+
@JsonSerializable(
118+
genericArgumentFactories: true,
119+
)
120+
class SubWithSubGenericArgumentFactoriesExt<T>
121+
extends SuperWithoutGenericArgumentFactories {}
122+
123+
@ShouldThrow(
124+
'The class `SubWithSubGenericArgumentFactoriesImpl` is annotated '
125+
'with `JsonSerializable` field `genericArgumentFactories: true`. '
126+
'`genericArgumentFactories: true` is not supported for classes '
127+
'that are sealed or have sealed superclasses.',
128+
todo: 'Remove the `genericArgumentFactories` option or '
129+
'remove the `sealed` keyword from the class.',
130+
element: 'SubWithSubGenericArgumentFactoriesImpl',
131+
)
132+
@JsonSerializable(
133+
genericArgumentFactories: true,
134+
)
135+
class SubWithSubGenericArgumentFactoriesImpl<T>
136+
implements SuperWithoutGenericArgumentFactories {}
137+
138+
@ShouldThrow(
139+
'The class `SubWithSubAndSuperGenericArgumentFactoriesExt` is annotated '
140+
'with `JsonSerializable` field `genericArgumentFactories: true`. '
141+
'`genericArgumentFactories: true` is not supported for classes '
142+
'that are sealed or have sealed superclasses.',
143+
todo: 'Remove the `genericArgumentFactories` option or '
144+
'remove the `sealed` keyword from the class.',
145+
element: 'SubWithSubAndSuperGenericArgumentFactoriesExt',
146+
)
147+
@JsonSerializable(
148+
genericArgumentFactories: true,
149+
)
150+
class SubWithSubAndSuperGenericArgumentFactoriesExt<T>
151+
extends SuperWithGenericArgumentFactories<T> {}
152+
153+
@ShouldThrow(
154+
'The class `SubWithSubAndSuperGenericArgumentFactoriesImpl` is annotated '
155+
'with `JsonSerializable` field `genericArgumentFactories: true`. '
156+
'`genericArgumentFactories: true` is not supported for classes '
157+
'that are sealed or have sealed superclasses.',
158+
todo: 'Remove the `genericArgumentFactories` option or '
159+
'remove the `sealed` keyword from the class.',
160+
element: 'SubWithSubAndSuperGenericArgumentFactoriesImpl',
161+
)
162+
@JsonSerializable(
163+
genericArgumentFactories: true,
164+
)
165+
class SubWithSubAndSuperGenericArgumentFactoriesImpl<T>
166+
implements SuperWithGenericArgumentFactories<T> {}

0 commit comments

Comments
 (0)