Migrate form_app to null safety (#925)

pull/927/head
John Ryan 3 years ago committed by GitHub
parent e2e2713986
commit d3c6253f85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'src/autofill.dart';
import 'src/form_widgets.dart';
@ -11,9 +10,6 @@ import 'src/http/mock_client.dart';
import 'src/sign_in_http.dart';
import 'src/validation.dart';
// Set up a mock HTTP client.
final http.Client httpClient = MockClient();
void main() {
runApp(const FormApp());
}
@ -23,7 +19,8 @@ final demos = [
name: 'Sign in with HTTP',
route: '/signin_http',
builder: (context) => SignInHttpDemo(
httpClient: httpClient,
// This sample uses a mock HTTP client.
httpClient: mockClient,
),
),
Demo(
@ -44,7 +41,7 @@ final demos = [
];
class FormApp extends StatelessWidget {
const FormApp({Key key}) : super(key: key);
const FormApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -58,7 +55,7 @@ class FormApp extends StatelessWidget {
}
class HomePage extends StatelessWidget {
const HomePage({Key key}) : super(key: key);
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
@ -73,16 +70,16 @@ class HomePage extends StatelessWidget {
}
class DemoTile extends StatelessWidget {
final Demo demo;
final Demo? demo;
const DemoTile({this.demo, Key key}) : super(key: key);
const DemoTile({this.demo, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
title: Text(demo.name),
title: Text(demo!.name),
onTap: () {
Navigator.pushNamed(context, demo.route);
Navigator.pushNamed(context, demo!.route);
},
);
}
@ -93,5 +90,5 @@ class Demo {
final String route;
final WidgetBuilder builder;
const Demo({this.name, this.route, this.builder});
const Demo({required this.name, required this.route, required this.builder});
}

@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
// Demonstrates how to use autofill hints. The full list of hints is here:
// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/text_editing/autofill_hint.dart
class AutofillDemo extends StatefulWidget {
const AutofillDemo({Key key}) : super(key: key);
const AutofillDemo({Key? key}) : super(key: key);
@override
_AutofillDemoState createState() => _AutofillDemoState();

@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
import 'package:intl/intl.dart' as intl;
class FormWidgetsDemo extends StatefulWidget {
const FormWidgetsDemo({Key key}) : super(key: key);
const FormWidgetsDemo({Key? key}) : super(key: key);
@override
_FormWidgetsDemoState createState() => _FormWidgetsDemoState();
@ -18,7 +18,7 @@ class _FormWidgetsDemoState extends State<FormWidgetsDemo> {
String description = '';
DateTime date = DateTime.now();
double maxValue = 0;
bool brushedTeeth = false;
bool? brushedTeeth = false;
bool enableFeature = false;
@override
@ -159,8 +159,8 @@ class _FormWidgetsDemoState extends State<FormWidgetsDemo> {
}
class _FormDatePicker<T> extends StatefulWidget {
final DateTime date;
final ValueChanged<T> onChanged;
final DateTime? date;
final ValueChanged<T>? onChanged;
const _FormDatePicker({
this.date,
@ -187,7 +187,7 @@ class _FormDatePickerState extends State<_FormDatePicker> {
style: Theme.of(context).textTheme.bodyText1,
),
Text(
intl.DateFormat.yMd().format(widget.date),
intl.DateFormat.yMd().format(widget.date!),
style: Theme.of(context).textTheme.subtitle1,
),
],
@ -197,7 +197,7 @@ class _FormDatePickerState extends State<_FormDatePicker> {
onPressed: () async {
var newDate = await showDatePicker(
context: context,
initialDate: widget.date,
initialDate: widget.date!,
firstDate: DateTime(1900),
lastDate: DateTime(2100),
);
@ -207,7 +207,7 @@ class _FormDatePickerState extends State<_FormDatePicker> {
return;
}
widget.onChanged(newDate);
widget.onChanged!(newDate);
},
)
],

@ -1,33 +1,18 @@
// Copyright 2020, the Flutter project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:mockito/mockito.dart';
class MockClient extends Mock implements http.Client {
MockClient() {
when(post('https://example.com/signin',
body: anyNamed('body'), headers: anyNamed('headers')))
.thenAnswer((answering) {
dynamic body = answering.namedArguments[const Symbol('body')];
import 'package:http/testing.dart';
if (body != null && body is String) {
var decodedJson = Map<String, dynamic>.from(
json.decode(body) as Map<String, dynamic>);
// Set up a mock HTTP client.
final http.Client mockClient = MockClient(_mockHandler);
if (decodedJson['email'] == 'root' &&
decodedJson['password'] == 'password') {
return Future.value(http.Response('', 200));
}
}
Future<http.Response> _mockHandler(http.Request request) async {
var decodedJson = Map<String, dynamic>.from(
json.decode(request.body) as Map<String, dynamic>);
return Future.value(http.Response('', 401));
});
when(post('https://example.com/signout'))
.thenAnswer((_) => Future.value(http.Response('', 401)));
if (decodedJson['email'] == 'root' && decodedJson['password'] == 'password') {
return http.Response('', 200);
}
return http.Response('', 401);
}

@ -12,8 +12,8 @@ part 'sign_in_http.g.dart';
@JsonSerializable()
class FormData {
String email;
String password;
String? email;
String? password;
FormData({
this.email,
@ -27,11 +27,11 @@ class FormData {
}
class SignInHttpDemo extends StatefulWidget {
final http.Client httpClient;
final http.Client? httpClient;
const SignInHttpDemo({
this.httpClient,
Key key,
Key? key,
}) : super(key: key);
@override
@ -80,8 +80,8 @@ class _SignInHttpDemoState extends State<SignInHttpDemo> {
child: const Text('Sign in'),
onPressed: () async {
// Use a JSON encoded string to send
var result = await widget.httpClient.post(
'https://example.com/signin',
var result = await widget.httpClient!.post(
Uri.parse('https://example.com/signin'),
body: json.encode(formData.toJson()),
headers: {'content-type': 'application/json'});

@ -1,7 +1,3 @@
// Copyright 2020, the Flutter project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'sign_in_http.dart';
@ -12,8 +8,8 @@ part of 'sign_in_http.dart';
FormData _$FormDataFromJson(Map<String, dynamic> json) {
return FormData(
email: json['email'] as String,
password: json['password'] as String,
email: json['email'] as String?,
password: json['password'] as String?,
);
}

@ -6,7 +6,7 @@ import 'package:english_words/english_words.dart' as english_words;
import 'package:flutter/material.dart';
class FormValidationDemo extends StatefulWidget {
const FormValidationDemo({Key key}) : super(key: key);
const FormValidationDemo({Key? key}) : super(key: key);
@override
_FormValidationDemoState createState() => _FormValidationDemoState();
@ -14,9 +14,9 @@ class FormValidationDemo extends StatefulWidget {
class _FormValidationDemoState extends State<FormValidationDemo> {
final _formKey = GlobalKey<FormState>();
String adjective;
String noun;
bool agreedToTerms = false;
String? adjective;
String? noun;
bool? agreedToTerms = false;
@override
Widget build(BuildContext context) {
@ -32,7 +32,7 @@ class _FormValidationDemoState extends State<FormValidationDemo> {
onPressed: () {
// Validate the form by getting the FormState from the GlobalKey
// and calling validate() on it.
var valid = _formKey.currentState.validate();
var valid = _formKey.currentState!.validate();
if (!valid) {
return;
}
@ -69,7 +69,7 @@ class _FormValidationDemoState extends State<FormValidationDemo> {
autofocus: true,
textInputAction: TextInputAction.next,
validator: (value) {
if (value.isEmpty) {
if (value!.isEmpty) {
return 'Please enter an adjective.';
}
if (english_words.adjectives.contains(value)) {
@ -92,7 +92,7 @@ class _FormValidationDemoState extends State<FormValidationDemo> {
// A text field that validates that the text is a noun.
TextFormField(
validator: (value) {
if (value.isEmpty) {
if (value!.isEmpty) {
return 'Please enter a noun.';
}
if (english_words.nouns.contains(value)) {
@ -151,7 +151,7 @@ class _FormValidationDemoState extends State<FormValidationDemo> {
formFieldState.errorText ?? "",
style: Theme.of(context)
.textTheme
.caption
.caption!
.copyWith(color: Theme.of(context).errorColor),
),
],

@ -234,7 +234,7 @@ packages:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.2"
version: "0.13.4"
http_multi_server:
dependency: transitive
description:
@ -248,7 +248,7 @@ packages:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
version: "4.0.0"
intl:
dependency: "direct main"
description:
@ -319,13 +319,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
mockito:
dependency: "direct main"
description:
name: mockito
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.7"
package_config:
dependency: transitive
description:
@ -374,7 +367,7 @@ packages:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.9"
version: "1.2.0"
shelf_web_socket:
dependency: transitive
description:
@ -486,4 +479,4 @@ packages:
source: hosted
version: "3.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
dart: ">=2.14.0 <3.0.0"

@ -4,15 +4,14 @@ publish_to: "none"
version: 1.0.0+1
environment:
sdk: ">=2.10.0 <3.0.0"
sdk: '>=2.12.0 <3.0.0'
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.0
intl: ^0.17.0
http: ^0.12.0
mockito: ^5.0.0
http: ^0.13.0
json_annotation: any
english_words: ^4.0.0

@ -6,9 +6,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:form_app/src/http/mock_client.dart';
import 'package:form_app/src/sign_in_http.dart';
import 'package:http/http.dart' as http;
final http.Client httpClient = MockClient();
void main() {
testWidgets('sign in', (tester) async {
@ -28,7 +25,7 @@ void main() {
Future<void> _signIn(WidgetTester tester, String email, String password) async {
await tester.pumpWidget(MaterialApp(
home: SignInHttpDemo(
httpClient: httpClient,
httpClient: mockClient,
),
));

Loading…
Cancel
Save