| // Copyright 2013 The Flutter 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:go_router/go_router.dart'; |
| import 'package:source_gen_test/annotations.dart'; |
| |
| @ShouldThrow('The @TypedGoRoute annotation can only be applied to classes.') |
| @TypedGoRoute(path: 'bob') // ignore: invalid_annotation_target |
| const int theAnswer = 42; |
| |
| // This test should be removed: dart enforces the `required` keyword. |
| @ShouldThrow('Missing `path` value on annotation.') |
| // ignore:missing_required_argument |
| @TypedGoRoute() |
| class MissingPathValue extends GoRouteData {} |
| |
| @ShouldThrow( |
| 'The @TypedGoRoute annotation can only be applied to classes that extend or ' |
| 'implement `GoRouteData`.', |
| ) |
| @TypedGoRoute(path: 'bob') |
| class AppliedToWrongClassType {} |
| |
| @ShouldThrow( |
| 'The @TypedGoRoute annotation must have a type parameter that matches the ' |
| 'annotated element.', |
| ) |
| @TypedGoRoute(path: 'bob') |
| class MissingTypeAnnotation extends GoRouteData {} |
| |
| @ShouldThrow( |
| 'Could not find a field for the path parameter "id".', |
| ) |
| @TypedGoRoute<BadPathParam>(path: 'bob/:id') |
| class BadPathParam extends GoRouteData {} |
| |
| @ShouldThrow( |
| 'The parameter type `Stopwatch` is not supported.', |
| ) |
| @TypedGoRoute<UnsupportedType>(path: 'bob/:id') |
| class UnsupportedType extends GoRouteData { |
| UnsupportedType({required this.id}); |
| final Stopwatch id; |
| } |
| |
| @ShouldThrow( |
| 'Required parameters cannot be nullable.', |
| ) |
| @TypedGoRoute<NullableRequiredParam>(path: 'bob/:id') |
| class NullableRequiredParam extends GoRouteData { |
| NullableRequiredParam({required this.id}); |
| final int? id; |
| } |
| |
| @ShouldThrow( |
| r'Parameters named `$extra` cannot be required.', |
| ) |
| @TypedGoRoute<ExtraMustBeOptional>(path: r'bob/:$extra') |
| class ExtraMustBeOptional extends GoRouteData { |
| ExtraMustBeOptional({required this.$extra}); |
| final int $extra; |
| } |
| |
| @ShouldThrow( |
| 'Missing param `id` in path.', |
| ) |
| @TypedGoRoute<MissingPathParam>(path: 'bob/') |
| class MissingPathParam extends GoRouteData { |
| MissingPathParam({required this.id}); |
| final String id; |
| } |
| |
| @ShouldGenerate(r''' |
| GoRoute get $enumParam => GoRouteData.$route( |
| path: '/:y', |
| factory: $EnumParamExtension._fromState, |
| ); |
| |
| extension $EnumParamExtension on EnumParam { |
| static EnumParam _fromState(GoRouterState state) => EnumParam( |
| y: _$EnumTestEnumMap._$fromName(state.params['y']!), |
| ); |
| |
| String get location => GoRouteData.$location( |
| '/${Uri.encodeComponent(_$EnumTestEnumMap[y]!)}', |
| ); |
| |
| void go(BuildContext context) => context.go(location, extra: this); |
| |
| void push(BuildContext context) => context.push(location, extra: this); |
| } |
| |
| const _$EnumTestEnumMap = { |
| EnumTest.a: 'a', |
| EnumTest.b: 'b', |
| EnumTest.c: 'c', |
| }; |
| |
| extension<T extends Enum> on Map<T, String> { |
| T _$fromName(String value) => |
| entries.singleWhere((element) => element.value == value).key; |
| } |
| ''') |
| @TypedGoRoute<EnumParam>(path: '/:y') |
| class EnumParam extends GoRouteData { |
| EnumParam({required this.y}); |
| final EnumTest y; |
| } |
| |
| enum EnumTest { |
| a(1), |
| b(3), |
| c(5); |
| |
| const EnumTest(this.x); |
| final int x; |
| } |
| |
| @ShouldGenerate(r''' |
| GoRoute get $defaultValueRoute => GoRouteData.$route( |
| path: '/default-value-route', |
| factory: $DefaultValueRouteExtension._fromState, |
| ); |
| |
| extension $DefaultValueRouteExtension on DefaultValueRoute { |
| static DefaultValueRoute _fromState(GoRouterState state) => DefaultValueRoute( |
| param: _$convertMapValue('param', state.queryParams, int.parse) ?? 0, |
| ); |
| |
| String get location => GoRouteData.$location( |
| '/default-value-route', |
| queryParams: { |
| if (param != 0) 'param': param.toString(), |
| }, |
| ); |
| |
| void go(BuildContext context) => context.go(location, extra: this); |
| |
| void push(BuildContext context) => context.push(location, extra: this); |
| } |
| |
| T? _$convertMapValue<T>( |
| String key, |
| Map<String, String> map, |
| T Function(String) converter, |
| ) { |
| final value = map[key]; |
| return value == null ? null : converter(value); |
| } |
| ''') |
| @TypedGoRoute<DefaultValueRoute>(path: '/default-value-route') |
| class DefaultValueRoute extends GoRouteData { |
| DefaultValueRoute({this.param = 0}); |
| final int param; |
| } |
| |
| @ShouldThrow( |
| 'Default value used with a nullable type. Only non-nullable type can have a default value.', |
| todo: 'Remove the default value or make the type non-nullable.', |
| ) |
| @TypedGoRoute<NullableDefaultValueRoute>(path: '/nullable-default-value-route') |
| class NullableDefaultValueRoute extends GoRouteData { |
| NullableDefaultValueRoute({this.param = 0}); |
| final int? param; |
| } |