Skip to content

Commit

Permalink
Testes de unidade e Widget com mocks: Boas práticas no Flutter
Browse files Browse the repository at this point in the history
  • Loading branch information
muriloao committed Mar 6, 2021
1 parent 454ca8d commit ec386a3
Show file tree
Hide file tree
Showing 25 changed files with 577 additions and 301 deletions.
8 changes: 5 additions & 3 deletions ios/Flutter/flutter_export_environment.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=C:\flutter"
export "FLUTTER_APPLICATION_PATH=C:\workspace\estudos\bytebank-alura"
export "FLUTTER_APPLICATION_PATH=C:\Users\Murilo Oliveira\workspace\bytebank-alura"
export "FLUTTER_TARGET=lib\main.dart"
export "FLUTTER_BUILD_DIR=build"
export "SYMROOT=${SOURCE_ROOT}/../build\ios"
export "OTHER_LDFLAGS=$(inherited) -framework Flutter"
export "FLUTTER_FRAMEWORK_DIR=C:\flutter\bin\cache\artifacts\engine\ios"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=false"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.packages"
32 changes: 0 additions & 32 deletions lib/components/editor.dart

This file was deleted.

5 changes: 4 additions & 1 deletion lib/components/transaction_auth_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'package:flutter/material.dart';

const Key transactionAuthDialogTextFieldPasswordKey =
Key('transactionAuthDialogTextFieldPassword');

class TransactionAuthDialog extends StatefulWidget {
final Function(String password) onConfirm;

Expand All @@ -12,14 +15,14 @@ class TransactionAuthDialog extends StatefulWidget {
}

class _TransactionAuthDialogState extends State<TransactionAuthDialog> {

final TextEditingController _passwordController = TextEditingController();

@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Authenticate'),
content: TextField(
key: transactionAuthDialogTextFieldPasswordKey,
controller: _passwordController,
obscureText: true,
maxLength: 4,
Expand Down
2 changes: 1 addition & 1 deletion lib/http/webclient.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ final Client client = HttpClientWithInterceptor.build(
requestTimeout: Duration(seconds: 5),
);

const String baseUrl = 'http://192.168.58.1:8080/transactions';
const String baseUrl = 'http://your_ip:8080/transactions';


36 changes: 26 additions & 10 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
import 'package:bytebank/database/dao/contact_dao.dart';
import 'package:bytebank/http/webclients/transaction_webclient.dart';
import 'package:bytebank/screens/dashboard.dart';
import 'package:bytebank/widgets/app_dependencies.dart';
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';

void main() {
runApp(BytebankApp());
runApp(BytebankApp(
contactDao: ContactDao(),
transactionWebClient: TransactionWebClient(),
));
}

class BytebankApp extends StatelessWidget {
final ContactDao contactDao;
final TransactionWebClient transactionWebClient;

BytebankApp({
@required this.contactDao,
@required this.transactionWebClient,
});

@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.green[900],
accentColor: Colors.blueAccent[700],
buttonTheme: ButtonThemeData(
buttonColor: Colors.blueAccent[700],
textTheme: ButtonTextTheme.primary,
return AppDependencies(
transactionWebClient: transactionWebClient,
contactDao: contactDao,
child: MaterialApp(
theme: ThemeData(
primaryColor: Colors.green[900],
accentColor: Colors.blueAccent[700],
buttonTheme: ButtonThemeData(
buttonColor: Colors.blueAccent[700],
textTheme: ButtonTextTheme.primary,
),
),
home: Dashboard(),
),
home: Dashboard(),
);
}
}
16 changes: 16 additions & 0 deletions lib/models/contact.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,20 @@ class Contact {
'name': name,
'accountNumber': accountNumber,
};

@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Contact &&
runtimeType == other.runtimeType &&
name == other.name &&
accountNumber == other.accountNumber;

@override
int get hashCode =>
name.hashCode ^
accountNumber.hashCode;



}
15 changes: 14 additions & 1 deletion lib/models/transaction.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Transaction {
this.id,
this.value,
this.contact,
);
) : assert(value > 0);

Transaction.fromJson(Map<String, dynamic> json) :
id = json['id'],
Expand All @@ -28,4 +28,17 @@ class Transaction {
return 'Transaction{value: $value, contact: $contact}';
}

@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Transaction &&
runtimeType == other.runtimeType &&
value == other.value &&
contact == other.contact;

@override
int get hashCode =>
value.hashCode ^
contact.hashCode;

}
14 changes: 0 additions & 14 deletions lib/models/transferencia.dart

This file was deleted.

11 changes: 9 additions & 2 deletions lib/screens/contact_form.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:bytebank/database/dao/contact_dao.dart';
import 'package:bytebank/models/contact.dart';
import 'package:bytebank/widgets/app_dependencies.dart';
import 'package:flutter/material.dart';

class ContactForm extends StatefulWidget {

@override
_ContactFormState createState() => _ContactFormState();
}
Expand All @@ -11,10 +13,10 @@ class _ContactFormState extends State<ContactForm> {
final TextEditingController _nameController = TextEditingController();
final TextEditingController _accountNumberController =
TextEditingController();
final ContactDao _dao = ContactDao();

@override
Widget build(BuildContext context) {
final dependencies = AppDependencies.of(context);
return Scaffold(
appBar: AppBar(
title: Text('New contact'),
Expand Down Expand Up @@ -56,7 +58,7 @@ class _ContactFormState extends State<ContactForm> {
final int accountNumber =
int.tryParse(_accountNumberController.text);
final Contact newContact = Contact(0, name, accountNumber);
_dao.save(newContact).then((id) => Navigator.pop(context));
_save(dependencies.contactDao, newContact, context);
},
),
),
Expand All @@ -66,4 +68,9 @@ class _ContactFormState extends State<ContactForm> {
),
);
}

void _save(ContactDao contactDao, Contact newContact, BuildContext context) async {
await contactDao.save(newContact);
Navigator.pop(context);
}
}
30 changes: 18 additions & 12 deletions lib/screens/contacts_list.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import 'package:bytebank/components/progress.dart';
import 'package:bytebank/database/dao/contact_dao.dart';
import 'package:bytebank/models/contact.dart';
import 'package:bytebank/screens/contact_form.dart';
import 'package:bytebank/screens/transaction_form.dart';
import 'package:bytebank/widgets/app_dependencies.dart';
import 'package:flutter/material.dart';

class ContactsList extends StatelessWidget {
final ContactDao _dao = ContactDao();
class ContactsList extends StatefulWidget {
@override
_ContactsListState createState() => _ContactsListState();
}

class _ContactsListState extends State<ContactsList> {
@override
Widget build(BuildContext context) {
final dependencies = AppDependencies.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Transfer'),
),
body: FutureBuilder<List<Contact>>(
initialData: List(),
future: _dao.findAll(),
future: dependencies.contactDao.findAll(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
Expand All @@ -31,7 +35,7 @@ class ContactsList extends StatelessWidget {
return ListView.builder(
itemBuilder: (context, index) {
final Contact contact = contacts[index];
return _ContactItem(
return ContactItem(
contact,
onClick: () {
Navigator.of(context).push(
Expand All @@ -51,11 +55,13 @@ class ContactsList extends StatelessWidget {
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ContactForm(),
),
);
Navigator.of(context)
.push(
MaterialPageRoute(
builder: (context) => ContactForm(),
),
)
.then((value) => setState(() {}));
},
child: Icon(
Icons.add,
Expand All @@ -65,11 +71,11 @@ class ContactsList extends StatelessWidget {
}
}

class _ContactItem extends StatelessWidget {
class ContactItem extends StatelessWidget {
final Contact contact;
final Function onClick;

_ContactItem(
ContactItem(
this.contact, {
@required this.onClick,
});
Expand Down
56 changes: 33 additions & 23 deletions lib/screens/dashboard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,49 @@ import 'package:bytebank/screens/transactions_list.dart';
import 'package:flutter/material.dart';

class Dashboard extends StatelessWidget {

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dashboard'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset('images/bytebank_logo.png'),
),
Container(
height: 120,
child: ListView(
scrollDirection: Axis.horizontal,
body: LayoutBuilder(
builder: (context, constraints) => SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: constraints.maxHeight,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_FeatureItem(
'Transfer',
Icons.monetization_on,
onClick: () => _showContactsList(context),
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset('images/bytebank_logo.png'),
),
_FeatureItem(
'Transaction Feed',
Icons.description,
onClick: () => _showTransactionsList(context),
Container(
height: 120,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
FeatureItem(
'Transfer',
Icons.monetization_on,
onClick: () => _showContactsList(context),
),
FeatureItem(
'Transaction Feed',
Icons.description,
onClick: () => _showTransactionsList(context),
),
],
),
),
],
),
),
],
),
),
);
}
Expand All @@ -57,12 +67,12 @@ class Dashboard extends StatelessWidget {
}
}

class _FeatureItem extends StatelessWidget {
class FeatureItem extends StatelessWidget {
final String name;
final IconData icon;
final Function onClick;

_FeatureItem(
FeatureItem(
this.name,
this.icon, {
@required this.onClick,
Expand Down
Loading

0 comments on commit ec386a3

Please sign in to comment.