Example for Unit Test (#52)

This commit is contained in:
Miten Gajjar
2020-07-06 00:12:20 +05:30
committed by GitHub
parent 07b7411e54
commit 389623e159
75 changed files with 1723 additions and 0 deletions

View File

@ -0,0 +1,72 @@
import 'package:unit_testing/model/lat_long.dart';
import 'package:unit_testing/model/location.dart';
class PlacesAPI {
final List<Location> _locations = [
Location(
id: 1,
name: "Kumarakom Backwaters",
country: "India",
info: "Keralas scenic backwaters, "
"edged with coconut palms, "
"lush green rice paddies and picturesque villages,"
"make for a beautiful escape from hectic city life.",
image: "assets/1.jpeg",
latlong: LatLong(
latitude: 9.9540358,
longitude: 76.2671037,
),
),
Location(
id: 2,
name: "Angel Falls",
country: "Venezuela",
info: "Venezuela overflows with natural wonders, "
"including the world's highest waterfall—the 3,212-foot cascades of Angel Falls,"
" located in the UNESCO-protected Canaima National Park. "
"Canaima is by far the country's most popular attraction,"
" and the falls stretch an astounding 19 times higher than Niagara Falls. ",
image: "assets/2.jpg",
latlong: LatLong(
latitude: 5.9689135,
longitude: -62.5376132,
),
),
Location(
id: 3,
name: "Avenue of the Baobabs",
country: "Madagascar",
info:
"Separated from continental Africa by 250 miles of water, Madagascar "
"is the greatest adventure"
" you haven't had yet. The island nation's secrets include giant moths, "
"bug-eyed lemurs, and places like the surreal Avenue of the Baobabs,"
" where the centuries-old trees reach heights of nearly 100 feet.",
image: "assets/3.jpg",
latlong: LatLong(
latitude: -20.2498059,
longitude: 44.4172047,
),
),
Location(
id: 4,
name: "Denali National Park",
country: " Alaska",
info: "Despite controversies over name changes and a shrinking elevation,"
" Denali's beauty is worth braving the extreme low temperatures. Make a "
"road trip out of your visit, seeing as "
"much of the 6 million acres of shimmering lakes and jagged mountains as you can.",
image: "assets/4.jpg",
latlong: LatLong(
latitude: 63.2092486,
longitude: -152.2366999,
),
),
];
Future<List<Location>> fetchAllPlaces() {
return Future.delayed(Duration(seconds: 3), () {
return _locations;
});
}
}

View File

@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
import 'package:unit_testing/model/location.dart';
class PlaceInfo extends StatelessWidget {
final Location data;
PlaceInfo({this.data});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(20),
padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
offset: Offset(0, 10),
blurRadius: 20,
color: Colors.black45,
)
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
data.name + "\n" + data.country,
style: TextStyle(
fontSize: 25,
color: Colors.black,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
SizedBox(
height: 20,
),
Image.asset(
data.image,
fit: BoxFit.fill,
),
SizedBox(
height: 20,
),
Text(
data.info,
style: TextStyle(fontSize: 23),
),
],
),
);
}
}

View File

@ -0,0 +1,33 @@
import 'package:unit_testing/api/Places.dart';
import 'package:unit_testing/model/location.dart';
class TouristPlaces {
static Future<List<Location>> getData() async {
// Here we can call a real API.
return await PlacesAPI().fetchAllPlaces();
}
}
class FormValidator {
static String validateEmail(String email) {
final pattern = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+");
if (email.isEmpty) {
return "please enter email";
} else if (!pattern.hasMatch(email)) {
return "please enter valid email";
} else {
return null;
}
}
static String validatePassword(String password) {
if (password.isEmpty) {
return "please enter your password";
} else if (password.length < 8) {
return "minimum lenght of password must be 8 characters";
} else {
return null;
}
}
}

View File

@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
import 'package:unit_testing/screens/home_screen.dart';
import 'package:unit_testing/screens/sign_in_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
initialRoute: "/",
routes: {
"/": (context) => SignInScreen(),
"/homeScreen": (context) => HomeScreen(),
},
);
}
}

View File

@ -0,0 +1,5 @@
class LatLong {
final double latitude;
final double longitude;
LatLong({this.latitude, this.longitude});
}

View File

@ -0,0 +1,18 @@
import 'lat_long.dart';
class Location {
final int id;
final String name;
final String image;
final LatLong latlong;
final String country;
final String info;
Location({
this.id,
this.name,
this.image,
this.latlong,
this.country,
this.info,
});
}

View File

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:unit_testing/components/place_info_card.dart';
import 'package:unit_testing/model/location.dart';
import '../helpers.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Unit Test'),
centerTitle: true,
),
body: FutureBuilder(
future: TouristPlaces.getData(), // this functions calls API.
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
final List<Location> data = snapshot.data;
return ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, index) => PlaceInfo(
data: data[index],
),
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
);
}
}

View File

@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:unit_testing/helpers.dart';
class SignInScreen extends StatefulWidget {
@override
_SignInScreenState createState() => _SignInScreenState();
}
class _SignInScreenState extends State<SignInScreen> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Material(
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Form(
key: _formKey,
child: Column(
children: [
Icon(
Icons.account_circle,
size: 200,
),
SizedBox(
height: 50,
),
TextFormField(
validator: (value) => FormValidator.validateEmail(value),
decoration: InputDecoration(
hintText: "Email",
),
),
SizedBox(
height: 50,
),
TextFormField(
validator: (value) => FormValidator.validatePassword(value),
decoration: InputDecoration(
hintText: "Password",
),
),
SizedBox(
height: 50,
),
RaisedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
Navigator.of(context).pushReplacementNamed('/homeScreen');
}
},
child: Text('Sign In'),
)
],
),
),
),
);
}
}