- Flutter app, with provider for dependency management.
- Always run flutter analyze to fix all errors, when there is errors, just run
dart fix --applybefore trying to manipulate the code by yourself - Always ensure your code is fully tested, with flutter test() or widgetTest(), add be generous with goldenTest and screen captures also
- Always prefer type-safe alternative to
dynamic,lateand other risky behaviors - Do not cast with
askeyword, but always prefer pattern matching to safely cast and test types - Never use the
dynamickeyword, norlate, but preferObject?which is safer - Always use flutter theme extension to allow UI customization, for every group of UI widgets you build, add a theme extension and refer to hit using context to customize the widgets.
- Always prefer
developer.logtoprint()anddebugPrint(), you can write extensive logging - Please don't unwrap
state.pathParameters['id']!;nor cast unsafelystate.extra as MyCard;. Prefer usage of libpackage:castor/castor.dartand convert tostate.extra.castOrNull<TarotCard>()and works with nullable. - For provider, prefer usage of
context.read(),context.select()andcontext.watch()instead ofConsumer<Xxx> - Prefer enums, static properties and other staticaly analyzed values instead of string-based calls
context.navigate('/draw'). - When you create a package, always provide an ./example app with extensive examples and documentation.
- For testing and mocking, instead of relying on various packages, just simply wrap service into provider injection that you will override in tests environments.
- All code and documentation in English
For typesafety, you can use the https://pub.dev/packages/castor as dependency
import 'package:castor/castor.dart';
import 'dart:convert';
void main() {
final dyn = jsonDecode('stuff'); // this is `dynamic`
final obj = (dyn as Object?);
// the basic [castOr] always expect to get an uwrapped value of the input type
int b = obj.castOr<String>(a, (_) => 'alternative string').length;
int c = castOr<int>(a, (_) => 'alternative string').length;
// the [castOrNull] equivalent just accept a nullable when casting is wrong
bool? asHelper = castOrNull<bool>(a, (_) => 'alternative string').length;
bool? asExt = obj?.castOrNull();
int? s = castOrNull<String>(a)?.length;
/// and with [a] an Object?
int s2 = a?.castOr<String>((val) => 'alternative string').length;
int? s = a?.castOrNull<String>(a)?.length;
}