Add `flutter_lints` to `add_to_app/plugin/flutter_module_using_plugin` (#812)

pull/833/head
Brett Morgan 4 years ago committed by GitHub
parent a405fc4a9d
commit c8112c88ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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

@ -11,12 +11,14 @@ import 'package:sensors/sensors.dart';
// This is on alternate entrypoint for this module to display Flutter UI in // This is on alternate entrypoint for this module to display Flutter UI in
// a (multi-)view integration scenario. // a (multi-)view integration scenario.
void main() { void main() {
runApp(Cell()); runApp(const Cell());
} }
class Cell extends StatefulWidget { class Cell extends StatefulWidget {
const Cell({Key key}) : super(key: key);
@override @override
State<StatefulWidget> createState() => new _CellState(); State<StatefulWidget> createState() => _CellState();
} }
class _CellState extends State<Cell> with WidgetsBindingObserver { class _CellState extends State<Cell> with WidgetsBindingObserver {
@ -29,8 +31,8 @@ class _CellState extends State<Cell> with WidgetsBindingObserver {
@override @override
void initState() { void initState() {
final channel = MethodChannel('dev.flutter.example/cell'); const channel = MethodChannel('dev.flutter.example/cell');
channel.setMethodCallHandler((MethodCall call) async { channel.setMethodCallHandler((call) async {
if (call.method == 'setCellNumber') { if (call.method == 'setCellNumber') {
setState(() { setState(() {
cellNumber = call.arguments as int; cellNumber = call.arguments as int;
@ -73,10 +75,10 @@ class _CellState extends State<Cell> with WidgetsBindingObserver {
home: Container( home: Container(
color: Colors.white, color: Colors.white,
child: Builder( child: Builder(
builder: (BuildContext context) { builder: (context) {
return Card( return Card(
// Mimic the platform Material look. // Mimic the platform Material look.
margin: EdgeInsets.symmetric(horizontal: 36, vertical: 24), margin: const EdgeInsets.symmetric(horizontal: 36, vertical: 24),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
@ -103,15 +105,14 @@ class _CellState extends State<Cell> with WidgetsBindingObserver {
bottom: 0, bottom: 0,
child: Opacity( child: Opacity(
opacity: 0.2, opacity: 0.2,
child: StreamBuilder( child: StreamBuilder<AccelerometerEvent>(
// Don't continuously rebuild for nothing when the // Don't continuously rebuild for nothing when the
// cell isn't visible. // cell isn't visible.
stream: appLifecycleState == AppLifecycleState.resumed stream: appLifecycleState == AppLifecycleState.resumed
? accelerometerEvents ? accelerometerEvents
: Stream.value(defaultPosition), : Stream.value(defaultPosition),
initialData: defaultPosition, initialData: defaultPosition,
builder: (BuildContext context, builder: (context, snapshot) {
AsyncSnapshot<AccelerometerEvent> snapshot) {
return Transform( return Transform(
// Figure out the phone's orientation relative // Figure out the phone's orientation relative
// to gravity's direction. Ignore the z vector. // to gravity's direction. Ignore the z vector.
@ -120,7 +121,7 @@ class _CellState extends State<Cell> with WidgetsBindingObserver {
..multiply(Matrix4.rotationY( ..multiply(Matrix4.rotationY(
snapshot.data.x / gravity * pi / 2)), snapshot.data.x / gravity * pi / 2)),
alignment: Alignment.center, alignment: Alignment.center,
child: FlutterLogo(size: 72)); child: const FlutterLogo(size: 72));
}, },
), ),
), ),

@ -20,7 +20,7 @@ void main() {
runApp( runApp(
ChangeNotifierProvider.value( ChangeNotifierProvider.value(
value: model, value: model,
child: MyApp(), child: const MyApp(),
), ),
); );
} }
@ -30,7 +30,7 @@ void main() {
// This is unfortunately in this file due to // This is unfortunately in this file due to
// https://github.com/flutter/flutter/issues/72630. // https://github.com/flutter/flutter/issues/72630.
void showCell() { void showCell() {
runApp(Cell()); runApp(const Cell());
} }
/// A simple model that uses a [MethodChannel] as the source of truth for the /// A simple model that uses a [MethodChannel] as the source of truth for the
@ -43,17 +43,17 @@ void showCell() {
class CounterModel extends ChangeNotifier { class CounterModel extends ChangeNotifier {
CounterModel() { CounterModel() {
_channel.setMethodCallHandler(_handleMessage); _channel.setMethodCallHandler(_handleMessage);
_channel.invokeMethod('requestCounter'); _channel.invokeMethod<void>('requestCounter');
} }
final _channel = MethodChannel('dev.flutter.example/counter'); final _channel = const MethodChannel('dev.flutter.example/counter');
int _count = 0; int _count = 0;
int get count => _count; int get count => _count;
void increment() { void increment() {
_channel.invokeMethod('incrementCounter'); _channel.invokeMethod<void>('incrementCounter');
} }
Future<dynamic> _handleMessage(MethodCall call) async { Future<dynamic> _handleMessage(MethodCall call) async {
@ -69,13 +69,15 @@ class CounterModel extends ChangeNotifier {
/// It offers two routes, one suitable for displaying as a full screen and /// It offers two routes, one suitable for displaying as a full screen and
/// another designed to be part of a larger UI. /// another designed to be part of a larger UI.
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
title: 'Flutter Module Title', title: 'Flutter Module Title',
routes: { routes: {
'/': (context) => FullScreenView(), '/': (context) => const FullScreenView(),
'/mini': (context) => Contents(), '/mini': (context) => const Contents(),
}, },
); );
} }
@ -84,11 +86,13 @@ class MyApp extends StatelessWidget {
/// Wraps [Contents] in a Material [Scaffold] so it looks correct when displayed /// Wraps [Contents] in a Material [Scaffold] so it looks correct when displayed
/// full-screen. /// full-screen.
class FullScreenView extends StatelessWidget { class FullScreenView extends StatelessWidget {
const FullScreenView({Key key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('Full-screen Flutter with plugin'), title: const Text('Full-screen Flutter with plugin'),
), ),
body: const Contents(showExit: true), body: const Contents(showExit: true),
); );
@ -104,7 +108,7 @@ class FullScreenView extends StatelessWidget {
class Contents extends StatelessWidget { class Contents extends StatelessWidget {
final bool showExit; final bool showExit;
const Contents({this.showExit = false}); const Contents({this.showExit = false, Key key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -120,7 +124,7 @@ class Contents extends StatelessWidget {
), ),
), ),
), ),
Positioned.fill( const Positioned.fill(
child: Opacity( child: Opacity(
opacity: .25, opacity: .25,
child: FittedBox( child: FittedBox(
@ -138,7 +142,7 @@ class Contents extends StatelessWidget {
'${mediaInfo.size.height.toStringAsFixed(1)}', '${mediaInfo.size.height.toStringAsFixed(1)}',
style: Theme.of(context).textTheme.headline5, style: Theme.of(context).textTheme.headline5,
), ),
SizedBox(height: 16), const SizedBox(height: 16),
Consumer<CounterModel>( Consumer<CounterModel>(
builder: (context, model, child) { builder: (context, model, child) {
return Text( return Text(
@ -147,12 +151,12 @@ class Contents extends StatelessWidget {
); );
}, },
), ),
SizedBox(height: 16), const SizedBox(height: 16),
Consumer<CounterModel>( Consumer<CounterModel>(
builder: (context, model, child) { builder: (context, model, child) {
return ElevatedButton( return ElevatedButton(
onPressed: () => model.increment(), onPressed: () => model.increment(),
child: Text('Tap me!'), child: const Text('Tap me!'),
); );
}, },
), ),
@ -160,18 +164,18 @@ class Contents extends StatelessWidget {
onPressed: () async { onPressed: () async {
// Use the url_launcher plugin to open the Flutter docs in // Use the url_launcher plugin to open the Flutter docs in
// a browser. // a browser.
final url = 'https://flutter.dev/docs'; const url = 'https://flutter.dev/docs';
if (await launcher.canLaunch(url)) { if (await launcher.canLaunch(url)) {
launcher.launch(url); launcher.launch(url);
} }
}, },
child: Text('Open Flutter Docs'), child: const Text('Open Flutter Docs'),
), ),
if (showExit) ...[ if (showExit) ...[
SizedBox(height: 16), const SizedBox(height: 16),
ElevatedButton( ElevatedButton(
onPressed: () => SystemNavigator.pop(), onPressed: () => SystemNavigator.pop(),
child: Text('Exit this screen'), child: const Text('Exit this screen'),
), ),
], ],
], ],

@ -55,6 +55,13 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" 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: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -72,6 +79,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.3" version: "0.6.3"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:

@ -16,6 +16,7 @@ dependencies:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^1.0.0
flutter: flutter:
uses-material-design: true uses-material-design: true

@ -6,16 +6,17 @@
// tree, read text, and verify that the values of widget properties are correct. // tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_module_using_plugin/main.dart'; import 'package:flutter_module_using_plugin/main.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class MockCounterModel extends ChangeNotifier implements CounterModel { class MockCounterModel extends ChangeNotifier implements CounterModel {
int _count = 0; int _count = 0;
@override
int get count => _count; int get count => _count;
@override
void increment() { void increment() {
_count++; _count++;
notifyListeners(); notifyListeners();
@ -23,13 +24,13 @@ class MockCounterModel extends ChangeNotifier implements CounterModel {
} }
void main() { void main() {
testWidgets('MiniView smoke test', (WidgetTester tester) async { testWidgets('MiniView smoke test', (tester) async {
// Build our app and trigger a frame. // Build our app and trigger a frame.
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: ChangeNotifierProvider<CounterModel>.value( home: ChangeNotifierProvider<CounterModel>.value(
value: MockCounterModel(), value: MockCounterModel(),
child: Contents(), child: const Contents(),
), ),
), ),
); );

Loading…
Cancel
Save