diff --git a/add_to_app/books/flutter_module_books/analysis_options.yaml b/add_to_app/books/flutter_module_books/analysis_options.yaml new file mode 100644 index 000000000..85f6fbe91 --- /dev/null +++ b/add_to_app/books/flutter_module_books/analysis_options.yaml @@ -0,0 +1,19 @@ +include: package:flutter_lints/flutter.yaml + +analyzer: + strong-mode: + implicit-casts: false + implicit-dynamic: false + +linter: + rules: + avoid_types_on_closure_parameters: true + avoid_void_async: true + cancel_subscriptions: true + close_sinks: true + directives_ordering: true + package_api_docs: true + package_prefixed_library_names: true + test_types_in_equals: true + throw_in_finally: true + unnecessary_statements: true diff --git a/add_to_app/books/flutter_module_books/lib/api.dart b/add_to_app/books/flutter_module_books/lib/api.dart index edb5cd804..e10f85c4d 100644 --- a/add_to_app/books/flutter_module_books/lib/api.dart +++ b/add_to_app/books/flutter_module_books/lib/api.dart @@ -41,7 +41,7 @@ class Book { } abstract class FlutterBookApi { - void displayBookDetails(Book arg); + void displayBookDetails(Book book); static void setup(FlutterBookApi api) { { const BasicMessageChannel channel = BasicMessageChannel( @@ -50,7 +50,7 @@ abstract class FlutterBookApi { if (api == null) { channel.setMessageHandler(null); } else { - channel.setMessageHandler((Object message) async { + channel.setMessageHandler((message) async { if (message == null) { return; } diff --git a/add_to_app/books/flutter_module_books/lib/main.dart b/add_to_app/books/flutter_module_books/lib/main.dart index a9a427925..0f15d5b9f 100644 --- a/add_to_app/books/flutter_module_books/lib/main.dart +++ b/add_to_app/books/flutter_module_books/lib/main.dart @@ -5,16 +5,18 @@ import 'package:flutter/material.dart'; import 'package:flutter_module_books/api.dart'; -void main() => runApp(MyApp()); +void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { + const MyApp({Key key}) : super(key: key); + @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( primaryColor: const Color(0xff6200ee), ), - home: BookDetail(), + home: const BookDetail(), ); } } @@ -37,7 +39,7 @@ class FlutterBookApiHandler extends FlutterBookApi { } class BookDetail extends StatefulWidget { - const BookDetail({this.hostApi, this.flutterApi}); + const BookDetail({this.hostApi, this.flutterApi, Key key}) : super(key: key); // These are the outgoing and incoming APIs that are here for injection for // tests. @@ -73,7 +75,7 @@ class _BookDetailState extends State { FlutterBookApi.setup(FlutterBookApiHandler( // The `FlutterBookApi` just has one method. Just give a closure for that // method to the handler class. - (Book book) { + (book) { setState(() { // This book model is what we're going to return to Kotlin eventually. // Keep it bound to the UI. @@ -107,9 +109,9 @@ class _BookDetailState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Book Details'), + title: const Text('Book Details'), leading: IconButton( - icon: Icon(Icons.clear), + icon: const Icon(Icons.clear), // Pressing clear cancels the edit and leaves the activity without // modification. onPressed: () { @@ -119,7 +121,7 @@ class _BookDetailState extends State { ), actions: [ IconButton( - icon: Icon(Icons.check), + icon: const Icon(Icons.check), // Pressing save sends the updated book to the platform. onPressed: () { hostApi.finishEditingBook(book); @@ -131,44 +133,44 @@ class _BookDetailState extends State { body: book == null // Draw a spinner until the platform gives us the book to show details // for. - ? Center(child: CircularProgressIndicator()) + ? const Center(child: CircularProgressIndicator()) : Focus( focusNode: textFocusNode, child: ListView( - padding: EdgeInsets.all(24), + padding: const EdgeInsets.all(24), children: [ TextField( controller: titleTextController, - decoration: InputDecoration( + decoration: const InputDecoration( border: OutlineInputBorder(), filled: true, hintText: "Title", labelText: "Title", ), ), - SizedBox(height: 24), + const SizedBox(height: 24), TextField( controller: subtitleTextController, maxLines: 2, - decoration: InputDecoration( + decoration: const InputDecoration( border: OutlineInputBorder(), filled: true, hintText: "Subtitle", labelText: "Subtitle", ), ), - SizedBox(height: 24), + const SizedBox(height: 24), TextField( controller: authorTextController, - decoration: InputDecoration( + decoration: const InputDecoration( border: OutlineInputBorder(), filled: true, hintText: "Author", labelText: "Author", ), ), - SizedBox(height: 32), - Divider(), + const SizedBox(height: 32), + const Divider(), Center( child: Padding( padding: const EdgeInsets.all(8.0), @@ -176,9 +178,9 @@ class _BookDetailState extends State { '${book.pageCount} pages ~ published ${book.publishDate}'), ), ), - Divider(), - SizedBox(height: 32), - Center( + const Divider(), + const SizedBox(height: 32), + const Center( child: Text( 'BOOK DESCRIPTION', style: TextStyle( @@ -188,7 +190,7 @@ class _BookDetailState extends State { ), ), ), - SizedBox(height: 12), + const SizedBox(height: 12), Text( book.summary, style: TextStyle(color: Colors.grey.shade600, height: 1.24), diff --git a/add_to_app/books/flutter_module_books/pubspec.lock b/add_to_app/books/flutter_module_books/pubspec.lock index c803e7133..dc97ee8d4 100644 --- a/add_to_app/books/flutter_module_books/pubspec.lock +++ b/add_to_app/books/flutter_module_books/pubspec.lock @@ -62,11 +62,25 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" matcher: dependency: transitive description: diff --git a/add_to_app/books/flutter_module_books/pubspec.yaml b/add_to_app/books/flutter_module_books/pubspec.yaml index 4594ca196..3030c6f71 100644 --- a/add_to_app/books/flutter_module_books/pubspec.yaml +++ b/add_to_app/books/flutter_module_books/pubspec.yaml @@ -17,6 +17,7 @@ dev_dependencies: mockito: ^4.1.1 flutter_test: sdk: flutter + flutter_lints: ^1.0.0 flutter: uses-material-design: true @@ -30,4 +31,4 @@ flutter: module: androidX: true androidPackage: dev.flutter.example.flutter_module_books - iosBundleIdentifier: dev.flutter.example.flutterModuleBooks \ No newline at end of file + iosBundleIdentifier: dev.flutter.example.flutterModuleBooks diff --git a/add_to_app/books/flutter_module_books/test/widget_test.dart b/add_to_app/books/flutter_module_books/test/widget_test.dart index 6f694de7c..259dcd209 100644 --- a/add_to_app/books/flutter_module_books/test/widget_test.dart +++ b/add_to_app/books/flutter_module_books/test/widget_test.dart @@ -9,8 +9,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; void main() { - testWidgets('Pressing clear calls the cancel API', - (WidgetTester tester) async { + testWidgets('Pressing clear calls the cancel API', (tester) async { MockHostBookApi mockHostApi = MockHostBookApi(); await tester.pumpWidget( @@ -24,8 +23,7 @@ void main() { verify(mockHostApi.cancel()); }); - testWidgets('Pressing done calls the finish editing API', - (WidgetTester tester) async { + testWidgets('Pressing done calls the finish editing API', (tester) async { MockHostBookApi mockHostApi = MockHostBookApi(); await tester.pumpWidget(