Merge with master and UserDatabase works
continuous-integration/drone/push Build is passing Details

ContinueLocalManager
Emre KARTAL 2 years ago
commit 205708fce7

@ -15,6 +15,14 @@ steps:
- cd ./Sources/bowlin_project/
- flutter build apk
- name: test
image: cirrusci/flutter:stable
commands:
- cd Sources/bowlin_project/
- flutter pub get
- flutter test --machine --coverage
depends_on: [ app-build ]
# build CONTAINER for sonar on flutter IMAGE
- name: code-analysis
image: cirrusci/flutter:stable
@ -28,8 +36,8 @@ steps:
- unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
- export PATH=$SONAR_SCANNER_HOME/bin:$PATH
- export SONAR_SCANNER_OPTS="-server"
- sonar-scanner -D sonar.projectKey=Bowl_in -D sonar.sources=./Sources/bowlin_project -D sonar.host.url=https://codefirst.iut.uca.fr/sonar
depends_on: [ app-build ]
- sonar-scanner -D sonar.projectKey=Bowl_in -D sonar.sources=./Sources/bowlin_project -D sonar.host.url=https://codefirst.iut.uca.fr/sonar -D sonar.flutter.coverage.reportPath=./Sources/bowlin_project/coverage/lcov.info
depends_on: [ test ]
# database container deployment
- name: deploy-container-postgresql
@ -49,11 +57,3 @@ steps:
CODEFIRST_CLIENTDRONE_ENV_POSTGRES_PASSWORD:
from_secret: db_password
ADMINS: emrekartal,louisonparant,davidd_almeida,lucasdelanier,arthurvalin
- name: deploy-adminer
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: adminer
CONTAINERNAME: adminer
COMMAND: create
OVERWRITE: true
ADMINS: emrekartal,louisonparant,davidd_almeida,lucasdelanier,arthurvalin

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 688 KiB

@ -17,6 +17,8 @@
[![Security Rating](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Bowl_in&metric=security_rating&token=88dd5f9f10bb02aede7a82a2bccf8c987af1ecab)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Bowl_in)
[![Vulnerabilities](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Bowl_in&metric=vulnerabilities&token=88dd5f9f10bb02aede7a82a2bccf8c987af1ecab)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Bowl_in)
[![Lines of Code](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Bowl_in&metric=ncloc&token=88dd5f9f10bb02aede7a82a2bccf8c987af1ecab)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Bowl_in)
[![Coverage](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=Bowl_in&metric=coverage&token=88dd5f9f10bb02aede7a82a2bccf8c987af1ecab)](https://codefirst.iut.uca.fr/sonar/dashboard?id=Bowl_in)
---
</div>

@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bowlin_project">
<application
android:label="bowlin_project"
android:label="Bowl'In"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity

@ -3,10 +3,4 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

@ -3,10 +3,4 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 33 KiB

@ -1,17 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 543 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 32 KiB

@ -1,8 +1,6 @@
import 'package:bowl_in/model/AbstractRound.dart';
import 'package:bowl_in/model/GameDetail.dart';
import 'package:bowl_in/model/Round.dart';
import 'package:bowl_in/views/ingame_screen2.dart';
import 'package:bowl_in/widgets/button_new_party.dart';
import 'package:flutter/cupertino.dart';
import 'package:go_router/go_router.dart';

@ -1,6 +1,5 @@
import '../../model/Stat.dart';
import '../../model/User.dart';
import '../fields/StatFields.dart';
import '../fields/UserFields.dart';
class UserMapper {
static Map<String, dynamic> toJson(User user) {
@ -20,7 +19,6 @@ class UserMapper {
json[UserFields.mail],
[],
[],
Stat(0,0,0,0,0,0,0,0)
);
}
}

@ -6,12 +6,17 @@ import '../fields/UserFields.dart';
import '../mappers/UserMapper.dart';
class UserDatabase {
UserDatabase();
static final UserDatabase instance = UserDatabase._init();
static Database? _database;
UserDatabase._init();
static const String tableUser = 'users';
Future<Database> get database async {
if (_database != null) return _database!;
@ -27,17 +32,17 @@ class UserDatabase {
}
Future _createDB(Database db, int version) async {
final idType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
final textType = 'TEXT NOT NULL';
final boolType = 'BOOLEAN NOT NULL';
final integerType = 'INTEGER NOT NULL';
const idType = 'INTEGER PRIMARY KEY AUTOINCREMENT';
const textType = 'TEXT NOT NULL';
const boolType = 'BOOLEAN NOT NULL';
const integerType = 'INTEGER NOT NULL';
await db.execute('''
CREATE TABLE $tableUser (
${UserFields.id} $idType,
${UserFields.name} $boolType,
${UserFields.image} $integerType,
${UserFields.mail} $textType,
${UserFields.image} $textType,
${UserFields.mail} $textType
)
''');
}

@ -1,16 +1,9 @@
import 'package:bowl_in/model/LocalManager/LocalData.dart';
import 'package:bowl_in/views/game_screen.dart';
import 'package:bowl_in/views/ingame_screen.dart';
import 'package:bowl_in/views/main_screen.dart';
import 'package:bowl_in/views/rank_screen.dart';
import 'package:bowl_in/views/welcome_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import 'package:bowl_in/config/app_router.dart';
import 'model/IManager.dart';
import 'model/StubManager/StubData.dart';
void main() {
runApp(const MyApp());
@ -18,7 +11,9 @@ void main() {
class MyApp extends StatelessWidget {
static IManager controller = LocalData();
const MyApp({super.key});
@override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);

@ -1,5 +1,7 @@
import 'Player.dart';
final maxScoreInFrame = 30;
abstract class AbstractRound {
int? _firstThrow;
int? _secondThrow;
@ -28,8 +30,12 @@ abstract class AbstractRound {
int? get points => _points;
set points(int? value) {
if((value??0)>=maxScoreInFrame){
_points=maxScoreInFrame;
}else {
_points = value;
}
}
int get number => _number;
@ -76,11 +82,14 @@ abstract class AbstractRound {
}
void update(int val){
print(" ROUND " + number.toString() + "UPDATE : " + val.toString());
points = (points ?? 0) + val;
previousRound?.update(val);
}
void unsubscribePreviousRound(){
print("UNSUBSCRIBE");
previousRound?.unsubscribePreviousRound();
previousRound=null;
}

@ -1,44 +1,17 @@
import 'Player.dart';
class Game {
int _id;
DateTime _date;
int _pointsCurrentUser;
bool _isFinished;
List<Player> _players = [];
final int _id;
final DateTime _date;
final int _pointsCurrentUser;
final List<Player> _players;
// Constructor
Game(this._id, this._date, this._pointsCurrentUser, this._isFinished,
Game(this._id, this._date, this._pointsCurrentUser,
this._players);
// Getters and setters
int get id => _id;
set id(int value) {
_id = value;
}
DateTime get date => _date;
set date(DateTime value) {
_date = value;
}
int get pointsCurrentUser => _pointsCurrentUser;
set pointsCurrentUser(int value) {
_pointsCurrentUser = value;
}
bool get isFinished => _isFinished;
set isFinished(bool value) {
_isFinished = value;
}
List<Player> get players => _players;
set playersId(List<Player> value) {
_players = value;
}
}

@ -1,26 +1,21 @@
import 'package:bowl_in/model/AbstractRound.dart';
import 'package:bowl_in/model/Game.dart';
import 'package:bowl_in/model/GamePlayer.dart';
import 'package:bowl_in/model/LastRound.dart';
import 'Player.dart';
import 'Round.dart';
import 'User.dart';
class GameDetail {
int _id;
DateTime _time;
final DateTime _time;
Player? _winner;
int _nbPoints;
bool _isFinished;
int _host;
List<AbstractRound> _rounds = [];
List<Player> _players = [];
final int _host;
final List<AbstractRound> _rounds = [];
final List<Player> _players;
final Map<Player, int> _points = {};
// Constructor
GameDetail(this._id, this._time, this._winner, this._nbPoints,
this._isFinished, this._host, this._players) {
GameDetail(this._id, this._time, this._winner, this._host, this._players) {
for (int i = 1; i <= 9; i++) {
players.forEach((element) {
this.rounds.add(Round(null, null, 0, element, i));
@ -29,7 +24,6 @@ class GameDetail {
players.forEach((element) {
this.rounds.add(LastRound(null, null, 0, element, 10, null));
});
}
// Getters and setters
@ -41,53 +35,24 @@ class GameDetail {
DateTime get time => _time;
set time(DateTime value) {
_time = value;
}
Player? get winner => _winner;
set winner(Player? value) {
_winner = value;
}
int get nbPoints => _nbPoints;
set nbPoints(int value) {
_nbPoints = value;
}
bool get isFinished => _isFinished;
set isFinished(bool value) {
_isFinished = value;
}
int get host => _host;
set host(int value) {
_host = value;
}
List<AbstractRound> get rounds => _rounds;
set rounds(List<AbstractRound> value) {
_rounds = value;
}
List<Player> get players => _players;
set players(List<Player> value) {
_players = value;
}
Map<Player, int> get points => _points;
void addGameToUsers() {
for (var p in players) {
if (p is User) {
p.games.add(Game(this.id, this.time, points[p] ?? 0, true, players));
p.games.add(Game(this.id, this.time, points[p] ?? 0, players));
p.stat.updateStats(this, p);
}
}
@ -101,15 +66,17 @@ class GameDetail {
void computeScores() {
print("====COMPUTE POINTS====");
for (var element in rounds) {
points[element.player] = (points[element.player] ?? 0) + (element.points ?? 0);
points[element.player] =
(points[element.player] ?? 0) + (element.points ?? 0);
print(element.points);
}
computeWinner();
addGameToUsers();
}
Map<Player, int> getRank() {
var sortedByValueMap = Map.fromEntries(
points.entries.toList()..sort((e1, e2) => e2.value.compareTo(e1.value)));
var sortedByValueMap = Map.fromEntries(points.entries.toList()
..sort((e1, e2) => e2.value.compareTo(e1.value)));
return sortedByValueMap;
}
}

@ -1,3 +1,4 @@
import 'package:bowl_in/model/AbstractRound.dart';
import 'package:bowl_in/model/IManager.dart';
import 'package:flutter/cupertino.dart';
@ -20,7 +21,14 @@ class GamePlayer {
_game = value;
}
void onNext(bool isRoundFinished, BuildContext context) {
AbstractRound? get currentRound {
if (currentRoundIndex < game.rounds.length){
return game.rounds[currentRoundIndex];
}
return null;
}
void onNext(bool isRoundFinished, BuildContext? context) {
if (isRoundFinished) {
print("++");
currentRoundIndex++;
@ -32,7 +40,7 @@ class GamePlayer {
_parent.gameMgr.addGame(game);
game.computeScores();
context.go("/scoreboard", extra: game);
context?.go("/scoreboard", extra: game);
} else {
print("IN GAME : " + currentRoundIndex.toString());
if (game.rounds[currentRoundIndex] is Round) {
@ -40,7 +48,7 @@ class GamePlayer {
} else {
print("LAST ROUND");
}
context.pushReplacement("/in-game",
context?.pushReplacement("/in-game",
extra: game.rounds[currentRoundIndex]);
}
}

@ -1,9 +1,7 @@
import 'GameDetail.dart';
import 'Player.dart';
import 'User.dart';
abstract class IGameManager {
// Methods
GameDetail getGameById(int id);
List<GameDetail> getGamesByPlayerId(int id);
List<GameDetail> getGamesByPlayer(Player user);

@ -1,6 +1,5 @@
import 'package:bowl_in/model/GameDetail.dart';
import 'package:bowl_in/model/GamePlayer.dart';
import 'User.dart';
import 'IUserManager.dart';
import 'IGameManager.dart';
@ -8,9 +7,9 @@ import 'IGameManager.dart';
abstract class IManager {
late User _userCurrent;
late GameDetail _gameCurrent;
late GamePlayer _gamePlayer = GamePlayer(this);
late IUserManager _userMgr;
late IGameManager _gameMgr;
late final GamePlayer _gamePlayer = GamePlayer(this);
late final IUserManager _userMgr;
late final IGameManager _gameMgr;
// Getters and setters
User get userCurrent => _userCurrent;
@ -21,10 +20,6 @@ abstract class IManager {
GamePlayer get gamePlayer => _gamePlayer;
set gamePlayer(GamePlayer value) {
_gamePlayer = value;
}
GameDetail get gameCurrent => _gameCurrent;
set gameCurrent(GameDetail value) {
@ -32,5 +27,14 @@ abstract class IManager {
}
IUserManager get userMgr => _userMgr;
IGameManager get gameMgr => _gameMgr;
set gameMgr(IGameManager value) {
_gameMgr = value;
}
set userMgr(IUserManager value) {
_userMgr = value;
}
}

@ -1,11 +1,10 @@
import 'package:bowl_in/model/AbstractRound.dart';
import 'Player.dart';
class LastRound extends AbstractRound {
int? _thirdThrow;
LastRound(super.firstThrow, super.secondThrow, super.points, super.player, super.number, this._thirdThrow);
LastRound(super.firstThrow, super.secondThrow, super.points, super.player,
super.number, this._thirdThrow);
int? get thirdThrow => _thirdThrow;
@ -38,6 +37,7 @@ class LastRound extends AbstractRound{
@override
void computePoints() {
points = (firstThrow ?? 0) + (secondThrow ?? 0) + (thirdThrow ?? 0);
print("Compute points : " + points.toString());
if (previousRound?.isStrike() ?? false) {
update(points ?? 0);
@ -95,7 +95,6 @@ class LastRound extends AbstractRound{
return (firstThrow ?? 0) + (secondThrow ?? 0) + (thirdThrow ?? 0);
}
@override
int getMaxPinsThisShot() {
if (firstThrow == null) {
@ -104,11 +103,10 @@ class LastRound extends AbstractRound{
return 10;
} else if ( secondThrow == null ){
return 10 - ( firstThrow ?? 0 );
}else if(secondThrow==10){
} else if ( ( firstThrow ?? 0 ) + ( secondThrow ?? 0 ) == 10 || secondThrow == 10 ){
return 10;
} else {
return 10 - ( secondThrow ?? 0 );
}
}
}

@ -1,24 +1,13 @@
import 'package:bowl_in/model/IManager.dart';
import 'package:localstorage/localstorage.dart';
import '../IGameManager.dart';
import '../IUserManager.dart';
import '../../database/sqlflite/UserDataBase.dart';
import 'GameManager.dart';
import 'UserManager.dart';
class LocalData extends IManager {
late IUserManager _userMgr;
late IGameManager _gameMgr;
final LocalStorage storage = LocalStorage('local_key');
final UserDatabase userDatabase = UserDatabase();
LocalData() {
_userMgr = UserManager(this);
_gameMgr = GameManager(this);
userMgr = UserManager(this);
gameMgr = GameManager(this);
}
IUserManager get userMgr => _userMgr;
IGameManager get gameMgr => _gameMgr;
}

@ -1,11 +1,7 @@
import 'dart:convert';
import 'package:bowl_in/model/IUserManager.dart';
import 'package:bowl_in/model/LocalManager/LocalData.dart';
import 'package:bowl_in/model/Player.dart';
import 'package:bowl_in/model/User.dart';
import '../Stat.dart';
import 'AuthManager.dart';
class UserManager extends IUserManager {
@ -13,42 +9,25 @@ class UserManager extends IUserManager {
// Constructor
UserManager(this.parent) : super(AuthManager(parent)) {
saveUser(
User(0, "Lucas", "./assets/images/image_user_red.png", "", [], []));
_initUser();
}
_initUser() async {
var userJson = await parent.storage.getItem('user');
if (userJson == null || userJson =='') {
User user2 = User(
1,
"Unknown",
"./assets/images/image_user_cyan.png",
"",
[],
[],
Stat(0, 0, 0, 0, 0, 0, 0, 0));
var user = await parent.userDatabase.readUser(0);
if (user == null) {
User user2 =
User(1, "Unknown", "./assets/images/image_user_cyan.png", "", [], []);
parent.userCurrent = user2;
} else {
Map<String, dynamic> userMap = json.decode(userJson);
User user = User(
userMap['_id'],
userMap['name'],
userMap['image'],
userMap['_mail'],
[],
[],
Stat(0, 0, 0, 0, 0, 0, 2.0, 3.0),
);
parent.userCurrent = user;
}
}
saveUser(User user) {
String userJson = json.encode(userToMap(user));
parent.storage.setItem('user', userJson);
parent.userDatabase.deleteUser(0);
parent.userDatabase.createUser(user);
}
Map<String, dynamic> userToMap(User user) {

@ -1,9 +1,8 @@
import 'package:bowl_in/model/AbstractRound.dart';
import 'GamePlayer.dart';
class Round extends AbstractRound {
Round(super.firstThrow, super.secondThrow, super.points, super.player, super.number);
Round(super.firstThrow, super.secondThrow, super.points, super.player,
super.number);
@override
bool computeNext(int val) {
@ -31,7 +30,6 @@ class Round extends AbstractRound{
if (previousRound?.isStrike() ?? false) {
previousRound?.update(points ?? 0);
}
unsubscribePreviousRound();
}
@override

@ -1,17 +1,15 @@
import 'package:bowl_in/model/GameDetail.dart';
import 'package:bowl_in/model/Player.dart';
import 'User.dart';
class Stat {
int _nbVictory;
int _nbGames;
int _highscore;
int _nbStrikes;
int _nbSpares;
int _nbScore;
double _avgScore;
double _avgPinsPerRound;
int _nbVictory = 0;
int _nbGames = 0;
int _highscore = 0;
int _nbStrikes = 0;
int _nbSpares = 0;
int _nbScore = 0;
double _avgScore = 0;
double _avgPinsPerRound = 0;
// Constructor
Stat(
@ -25,6 +23,9 @@ class Stat {
this._avgPinsPerRound,
);
Stat.empty();
// Getters and setters
int get nbVictory => _nbVictory;
@ -86,27 +87,14 @@ class Stat {
double totalpins = 0;
for (var r in gd.rounds) {
if (p == r.player) {
nbStrikes += r.getNbStrike();
nbSpares += r.getNbSpares();
totalpins = totalpins + r.getPinsKnockedDown();
}
}
avgPinsPerRound = ((avgPinsPerRound * (nbGames-1)) + (totalpins/10))/nbGames;
avgPinsPerRound =
((avgPinsPerRound * (nbGames - 1)) + (totalpins / 10)) / nbGames;
}
// Serialize to JSON
Map<String, dynamic> toJson() => {
'nbVictory': nbVictory,
'nbGames': nbGames,
'highscore': highscore,
'nbStrikes': nbStrikes,
'nbSpares': nbSpares,
'nbScore': nbScore,
'avgScore': avgScore,
'avgPinsPerRound': avgPinsPerRound,
};
}

@ -14,7 +14,7 @@ class AuthManager extends IAuthManager {
bool verifiedUser(String mail, String password) {
for (var user in parent.players) {
if (user is User && user.mail == mail) {
parent.userCurrent = user as User;
parent.userCurrent = user;
return true;
}
}

@ -1,11 +1,9 @@
library StubLib;
import '../Game.dart';
import '../IGameManager.dart';
import '../GameDetail.dart';
import '../Player.dart';
import '../User.dart';
import '../Guest.dart';
import 'StubData.dart';
class GameManager extends IGameManager {

@ -2,35 +2,24 @@ library StubLib;
import '../Guest.dart';
import '../IManager.dart';
import '../Game.dart';
import '../IUserManager.dart';
import '../IGameManager.dart';
import '../Player.dart';
import '../Round.dart';
import '../User.dart';
import '../Achievement.dart';
import '../GameDetail.dart';
import '../Stat.dart';
import 'UserManager.dart';
import 'GameManager.dart';
class StubData extends IManager {
late IUserManager _userMgr;
late IGameManager _gameMgr;
StubData() {
_userMgr = UserManager(this);
_gameMgr = GameManager(this);
userMgr = UserManager(this);
gameMgr = GameManager(this);
_initRounds();
_initGameDetails();
_initGame();
userCurrent = players[8] as User;
}
IUserManager get userMgr => _userMgr;
IGameManager get gameMgr => _gameMgr;
List<Player> players = [
Guest("Mathieu"),
Guest("Robin"),
@ -39,91 +28,49 @@ class StubData extends IManager {
Guest("Louison"),
Guest("Arthur"),
Guest("David"),
User(
8,
"Emre",
"./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr",
[
User(8, "Emre", "./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr", [
Achievement("5 games"),
Achievement("2 strikes in a row"),
Achievement("Win a game")
],
[],
Stat(0, 0, 0, 0, 0, 0, 0, 0)),
User(
9,
"Dave",
"./assets/images/image_user_cyan.png",
"david.d_almeida@etu.uca.fr",
[
], []),
User(9, "Dave", "./assets/images/image_user_cyan.png",
"david.d_almeida@etu.uca.fr", [
Achievement("5 games"),
Achievement("0 point"),
Achievement("Win a game")
],
[
User(
21,
"Arthur",
"./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr",
[
], [
User(21, "Arthur", "./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr", [
Achievement("5 games"),
Achievement("2 strikes in a row"),
Achievement("Win a game")
],
[],
Stat(0, 0, 0, 0, 0, 0, 0, 0)),
User(
22,
"Louison",
"./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr",
[
], []),
User(22, "Louison", "./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr", [
Achievement("5 games"),
Achievement("2 strikes in a row"),
Achievement("Win a game")
],
[],
Stat(10, 12, 150, 7, 6, 700, 58.33, 30.2)),
User(
23,
"Owen",
"./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr",
[
], []),
User(23, "Owen", "./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr", [
Achievement("5 games"),
Achievement("2 strikes in a row"),
Achievement("Win a game")
],
[],
Stat(10, 12, 10, 7, 6, 700, 58.33, 30.2)),
User(
24,
"LULU",
"./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr",
[
], []),
User(24, "LULU", "./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr", [
Achievement("5 games"),
Achievement("2 strikes in a row"),
Achievement("Win a game")
],
[],
Stat(10, 12, 40, 7, 6, 700, 58.33, 30.2)),
User(
25,
"Raphael",
"./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr",
[
], []),
User(25, "Raphael", "./assets/images/image_user_cyan.png",
"emre.kartal@etu.uca.fr", [
Achievement("5 games"),
Achievement("2 strikes in a row"),
Achievement("Win a game")
],
[],
Stat(10, 12, 76, 7, 6, 700, 58.33, 30.2)),
],
Stat(0, 0, 0, 0, 0, 0, 0, 0))
], []),
])
];
List<GameDetail> _gameDetails = [];
@ -172,8 +119,6 @@ class StubData extends IManager {
List<Round> get rounds => _rounds;
List<Game> _games = [];
void _initGame() {
// games.add(Game(
// gameDetails[0].id,

@ -1,13 +1,10 @@
library StubLib;
import '../IUserManager.dart';
import '../IAuthManager.dart';
import '../Player.dart';
import '../User.dart';
import 'AuthManager.dart';
import 'StubData.dart';
import '../Player.dart';
import '../Stat.dart';
class UserManager extends IUserManager {
final StubData parent;

@ -10,12 +10,12 @@ class User extends Player {
String _mail;
List<Achievement> _achievements = <Achievement>[];
List<User> _friends = <User>[];
Stat _stat;
final Stat _stat = Stat.empty();
List<Game> games = [];
// Constructor
User(this._id, String name, String image, this._mail, this._achievements,
this._friends, this._stat)
this._friends)
: super(name, image);
int get id => _id;
@ -41,8 +41,4 @@ class User extends Player {
Stat get stat => _stat;
set stat(Stat value) {
_stat = value;
}
}

@ -1,17 +1,10 @@
import 'package:bowl_in/main.dart';
import 'package:bowl_in/model/GameDetail.dart';
import 'package:bowl_in/model/GamePlayer.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import '../model/Game.dart';
import '../model/Guest.dart';
import '../model/Player.dart';
import '../widgets/button_new_party.dart';
import '../widgets/ingame_widgets.dart';
import '../widgets/scores_list_widget.dart';
class InGameScreen extends StatefulWidget {
const InGameScreen({Key? key}) : super(key: key);
@ -57,12 +50,7 @@ class _InGameScreenState extends State<InGameScreen> {
Spacer(),
ElevatedButton(
onPressed: () {
GameDetail gd = GameDetail(
-1,
DateTime.now(),
null,
0,
false,
GameDetail gd = GameDetail(-1, DateTime.now(), null,
MyApp.controller.userCurrent.id, listPlayers);
MyApp.controller.gamePlayer.game = gd;
@ -81,8 +69,8 @@ class _InGameScreenState extends State<InGameScreen> {
width: 7,
color: Color(0xff1ABAE0),
),
onPrimary: Colors.transparent,
primary: Colors.transparent,
backgroundColor: Colors.transparent,
foregroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(55),
),

@ -3,11 +3,7 @@ import 'package:bowl_in/model/AbstractRound.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../model/Round.dart';
import '../widgets/button_new_party.dart';
import '../widgets/ingame_widgets.dart';
import '../widgets/scores_list_widget.dart';
class InGameScreen2 extends StatefulWidget {
final AbstractRound currentRound;
@ -93,8 +89,8 @@ class _InGameScreen2State extends State<InGameScreen2> {
width: 7,
color: Color(0xff1ABAE0),
),
onPrimary: Colors.transparent,
primary: Colors.transparent,
backgroundColor: Colors.transparent,
foregroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(55),
),

@ -66,8 +66,8 @@ class ButtonConnexion extends StatelessWidget {
width: 7,
color: Color(0xffFF419B),
),
onPrimary: Colors.white,
primary: Color(0xffF40375),
foregroundColor: Colors.white,
backgroundColor: Color(0xffF40375),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(35),
),

@ -3,11 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import '../main.dart';
import '../model/GameDetail.dart';
import '../model/Player.dart';
import '../model/User.dart';
import 'ingame_widgets.dart';
class ButtonNewParty extends StatelessWidget {
@ -21,8 +17,8 @@ class ButtonNewParty extends StatelessWidget {
width: 4,
color: Color(0xffFF419B),
),
onPrimary: Colors.white,
primary: Color(0xffF40375),
foregroundColor: Colors.white,
backgroundColor: Color(0xffF40375),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(35),
),
@ -127,8 +123,8 @@ class NewGameModal extends StatelessWidget {
fontWeight: FontWeight.bold, fontSize: 18),
),
style: ElevatedButton.styleFrom(
onPrimary: Colors.white,
primary: Color(0xffF40375),
foregroundColor: Colors.white,
backgroundColor: Color(0xffF40375),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
@ -229,8 +225,8 @@ class ButtonJoinParty extends StatelessWidget {
width: 4,
color: Color(0xff6B6588),
),
onPrimary: Colors.white,
primary: Color(0xff45405D),
foregroundColor: Colors.white,
backgroundColor: Color(0xff45405D),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(35),
),

@ -1,13 +1,9 @@
import 'dart:ui';
import 'package:bowl_in/main.dart';
import 'package:bowl_in/widgets/profil_listpodium_widget.dart';
import 'package:bowl_in/widgets/scores_list_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import '../model/AbstractRound.dart';
import '../model/GameDetail.dart';
import '../model/Guest.dart';
@ -170,8 +166,8 @@ class _FinalScoreBoardState extends State<FinalScoreBoard> {
width: 7,
color: Color(0xff1ABAE0),
),
onPrimary: Colors.transparent,
primary: Colors.transparent,
foregroundColor: Colors.transparent,
backgroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(55),
),
@ -252,7 +248,8 @@ class PodiumGameOverWidget extends StatelessWidget {
class InGameCardConfig extends StatefulWidget {
final List<Player> listPlayer;
const InGameCardConfig({Key? key, required this.listPlayer}) : super(key: key);
const InGameCardConfig({Key? key, required this.listPlayer})
: super(key: key);
@override
State<InGameCardConfig> createState() => _InGameCardConfigState();
@ -266,14 +263,12 @@ class _InGameCardConfigState extends State<InGameCardConfig> {
void onDelete(Player p) {
setState(() {
widget.listPlayer.remove(p);
});
}
void onReorder(int oldIndex, int newIndex) {
setState(() {
if (oldIndex < newIndex) {
newIndex -= 1;
}
@ -325,7 +320,11 @@ class _InGameCardConfigState extends State<InGameCardConfig> {
],
),
)),
ListUserInGame(listPlayer: widget.listPlayer, onDelete: onDelete, onReorder: onReorder,),
ListUserInGame(
listPlayer: widget.listPlayer,
onDelete: onDelete,
onReorder: onReorder,
),
Spacer(),
Image(
image: AssetImage("assets/images/start_sentence.png"),
@ -350,7 +349,7 @@ class _InGameCardConfigState extends State<InGameCardConfig> {
style: ElevatedButton.styleFrom(
elevation: 5,
shadowColor: Color(0xffB70056),
primary: Color(0xffF40375),
backgroundColor: Color(0xffF40375),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
@ -367,14 +366,18 @@ class ListUserInGame extends StatefulWidget {
final List<Player> listPlayer;
final Function(Player) onDelete;
final Function(int, int) onReorder;
const ListUserInGame({Key? key, required this.listPlayer, required this.onDelete, required this.onReorder}) : super(key: key);
const ListUserInGame(
{Key? key,
required this.listPlayer,
required this.onDelete,
required this.onReorder})
: super(key: key);
@override
State<ListUserInGame> createState() => _ListUserInGameState();
}
class _ListUserInGameState extends State<ListUserInGame> {
@override
Widget build(BuildContext context) {
return Padding(
@ -389,7 +392,11 @@ class _ListUserInGameState extends State<ListUserInGame> {
child: ReorderableListView.builder(
itemCount: widget.listPlayer.length,
itemBuilder: (context, index) {
return UserInGame(key:ValueKey(widget.listPlayer[index]) ,player: widget.listPlayer[index], onDelete: widget.onDelete, index: index);
return UserInGame(
key: ValueKey(widget.listPlayer[index]),
player: widget.listPlayer[index],
onDelete: widget.onDelete,
index: index);
},
onReorder: widget.onReorder,
),
@ -418,7 +425,12 @@ class UserInGame extends StatefulWidget {
final Player player;
final Function(Player) onDelete;
final int index;
const UserInGame({Key? key, required this.player, required this.onDelete, required this.index}) : super(key: key);
const UserInGame(
{Key? key,
required this.player,
required this.onDelete,
required this.index})
: super(key: key);
@override
State<UserInGame> createState() => _UserInGameState();
@ -472,29 +484,26 @@ class _UserInGameState extends State<UserInGame> {
),
cursorColor: Colors.purple,
textAlign: TextAlign.left,
onChanged: (str)=> widget.player.name=str
,
onChanged: (str) => widget.player.name = str,
),
),
)
: SizedBox(
width: 220,
child: Text(
widget.player.name,
child: Text(widget.player.name,
style: GoogleFonts.roboto(
fontSize: 18,
decoration: TextDecoration.none,
color: Color(0xff241E40))
),
color: Color(0xff241E40))),
),
(widget.player is User && (widget.player as User).id == MyApp.controller.userCurrent.id) ?
Icon(Icons.lock, color: Colors.amber) :
GestureDetector(
(widget.player is User &&
(widget.player as User).id == MyApp.controller.userCurrent.id)
? Icon(Icons.lock, color: Colors.amber)
: GestureDetector(
onTap: () {
widget.onDelete(widget.player);
},
child: Icon(Icons.close)
),
child: Icon(Icons.close)),
Spacer()
],
),
@ -518,8 +527,6 @@ class InGameCardThrow extends StatefulWidget {
}
class _InGameCardThrowState extends State<InGameCardThrow> {
GlobalKey<_NumberPadState> _numberPadKey = GlobalKey();
void initState() {
super.initState();
}

@ -2,9 +2,7 @@ import 'package:bowl_in/widgets/scores_list_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../main.dart';
import '../model/Player.dart';
import '../model/User.dart';
class ProfilPodiumWidget extends StatelessWidget {

@ -2,7 +2,6 @@ import 'package:bowl_in/main.dart';
import 'package:bowl_in/widgets/button_new_party.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';

@ -156,10 +156,10 @@ packages:
dependency: "direct main"
description:
name: go_router
sha256: e2a90e1d4eed378ea12e0771be9e32766a2f8d2de3064e42f3a55f1b04fb8af8
sha256: b90b9aaa7723ca7159a81c0cd3be8108c74c986c3fbc41d413fd82ea164733ea
url: "https://pub.dev"
source: hosted
version: "6.4.1"
version: "6.4.0"
google_fonts:
dependency: "direct main"
description:

@ -0,0 +1,37 @@
import 'package:bowl_in/model/GameDetail.dart';
import 'package:bowl_in/model/Guest.dart';
import 'package:bowl_in/model/IManager.dart';
import 'package:bowl_in/model/Player.dart';
import 'package:bowl_in/model/StubManager/StubData.dart';
import 'package:flutter_test/flutter_test.dart';
void testManager(IManager mgr) {
test("Test manager " + mgr.runtimeType.toString(), () {
expect(mgr.userCurrent, mgr.userMgr.getUsersByName("Dave").first);
expect(mgr.userCurrent, mgr.userMgr.getUserById(mgr.userCurrent.id));
List<Player> players = [mgr.userCurrent, Guest("Emre")];
GameDetail gd = GameDetail(
mgr.gameMgr.getNextId(), DateTime.now(), null, mgr.userCurrent.id, players);
expect(gd.players, players);
expect(gd.host, mgr.userCurrent.id);
mgr.gameMgr.addGame(gd);
expect(gd, mgr.gameMgr.getGameById(gd.id));
expect(gd, mgr.gameMgr.getGamesByPlayer(mgr.userCurrent).first);
expect(gd, mgr.gameMgr.getGamesByPlayerId(mgr.userCurrent.id).first);
expect(players, mgr.gameMgr.getPlayersByIdGame(gd.id));
expect(gd, mgr.gameMgr.getGamesByPlayers(players).first);
});
}
void main() {
testManager(StubData());
}

@ -0,0 +1,140 @@
import 'package:bowl_in/model/AbstractRound.dart';
import 'package:bowl_in/model/GameDetail.dart';
import 'package:bowl_in/model/GamePlayer.dart';
import 'package:bowl_in/model/Guest.dart';
import 'package:bowl_in/model/IManager.dart';
import 'package:bowl_in/model/Player.dart';
import 'package:bowl_in/model/StubManager/StubData.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test("Just strikes", (){
final IManager mgr = StubData();
final List<Player> listPlayers = [mgr.userCurrent, Guest("Lucas")];
final GameDetail gd = GameDetail(
-1,
DateTime.now(),
null,
mgr.userCurrent.id,
listPlayers);
mgr.gamePlayer.game = gd;
mgr.gamePlayer.onNext(false, null);
AbstractRound? currentRound = mgr.gamePlayer.currentRound;
while (currentRound != null) {
bool isFinished = currentRound.computeNext(10);
if (currentRound.isSpareOrStrike()) {
mgr.gamePlayer.onSpareOrStrike();
}
mgr.gamePlayer.onNext(isFinished, null);
currentRound = mgr.gamePlayer.currentRound;
}
final int score = gd
.getRank()
.values
.first;
expect(score, 300);
});
test("Classic game", (){
final IManager mgr = StubData();
final List<Player> listPlayers = [mgr.userCurrent, Guest("Lucas")];
final DateTime dateGame = DateTime.now();
final GameDetail gd = GameDetail(
-1,
dateGame,
null,
mgr.userCurrent.id,
listPlayers);
mgr.gamePlayer.game = gd;
mgr.gamePlayer.onNext(false, null);
makeThrow(7, mgr.gamePlayer);
makeThrow(2, mgr.gamePlayer);
makeThrow(10, mgr.gamePlayer);
makeThrow(5, mgr.gamePlayer);
makeThrow(5, mgr.gamePlayer);
makeThrow(5, mgr.gamePlayer);
makeThrow(5, mgr.gamePlayer);
makeThrow(3, mgr.gamePlayer);
makeThrow(7, mgr.gamePlayer);
makeThrow(0, mgr.gamePlayer);
makeThrow(7, mgr.gamePlayer);
makeThrow(10, mgr.gamePlayer);
makeThrow(0, mgr.gamePlayer);
makeThrow(0, mgr.gamePlayer);
makeThrow(9, mgr.gamePlayer);
makeThrow(0, mgr.gamePlayer);
makeThrow(0, mgr.gamePlayer);
makeThrow(10, mgr.gamePlayer);
makeThrow(2, mgr.gamePlayer);
makeThrow(2, mgr.gamePlayer);
makeThrow(5, mgr.gamePlayer);
makeThrow(5, mgr.gamePlayer);
makeThrow(10, mgr.gamePlayer);
makeThrow(3, mgr.gamePlayer);
makeThrow(2, mgr.gamePlayer);
makeThrow(1, mgr.gamePlayer);
makeThrow(2, mgr.gamePlayer);
makeThrow(7, mgr.gamePlayer);
makeThrow(1, mgr.gamePlayer);
makeThrow(4, mgr.gamePlayer);
makeThrow(6, mgr.gamePlayer);
makeThrow(1, mgr.gamePlayer);
makeThrow(7, mgr.gamePlayer);
makeThrow(10, mgr.gamePlayer);
makeThrow(6, mgr.gamePlayer);
makeThrow(2, mgr.gamePlayer);
makeThrow(8, mgr.gamePlayer);
makeThrow(1, mgr.gamePlayer);
final Iterable<int> score = gd
.getRank()
.values;
expect(score.first, 128);
expect(score.last, 95);
expect(mgr.userCurrent.games.length, 1);
expect(mgr.userCurrent.games.first.id, mgr.gamePlayer.game.id);
expect(mgr.userCurrent.games.first.pointsCurrentUser, 128);
expect(mgr.userCurrent.games.first.date, dateGame);
expect(mgr.userCurrent.games.first.players, listPlayers);
});
}
void makeThrow(int input, GamePlayer gamePlayer){
AbstractRound currentRound = gamePlayer.currentRound!;
bool isFinished = currentRound.computeNext(input);
if (currentRound.isSpareOrStrike()) {
gamePlayer.onSpareOrStrike();
}
gamePlayer.onNext(isFinished, null);
}

@ -0,0 +1,84 @@
import 'package:bowl_in/model/LastRound.dart';
import 'package:bowl_in/model/Round.dart';
import 'package:bowl_in/model/User.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test("Test Round", () {
User u = User(
1,
"Louison",
"Sources/bowlin_project/assets/images/image_user_pink.png",
"loparant@gmail.com", [], []);
Round r = Round(null, null, null, u, 1);
expect(r.getMaxPinsThisShot(), 10);
expect(r.isSpareOrStrike(), false);
r.computeNext(4);
expect(r.getMaxPinsThisShot(), 6);
r.computeNext(6);
expect(r.isSpare(), true);
expect(r.isSpareOrStrike(), true);
expect(r.isStrike(), false);
expect(r.getNbSpares(), 1);
expect(r.getNbStrike(), 0);
Round r2 = Round(null, null, null, u, 2);
r2.computeNext(10);
expect(r2.isSpare(), false);
expect(r2.isStrike(), true);
expect(r2.isSpareOrStrike(), true);
expect(r2.getNbSpares(), 0);
expect(r2.getNbStrike(), 1);
Round r3 = Round(null, null, null, u, 2);
r3.computeNext(2);
r3.computeNext(5);
expect(r3.getPinsKnockedDown(), 7);
});
test("Test LastRound", () {
User u = User(
1,
"Louison",
"Sources/bowlin_project/assets/images/image_user_pink.png",
"loparant@gmail.com", [], []);
LastRound r = LastRound(null, null, null, u, 1, null);
expect(r.getMaxPinsThisShot(), 10);
expect(r.isSpareOrStrike(), false);
r.computeNext(10);
expect(r.getMaxPinsThisShot(), 10);
r.computeNext(10);
expect(r.getMaxPinsThisShot(), 10);
r.computeNext(10);
expect(r.getPinsKnockedDown(), 30);
expect(r.getNbSpares(), 0);
expect(r.getNbStrike(), 3);
LastRound r2 = LastRound(null, null, null, u, 1, null);
r2.computeNext(1);
expect(r2.getMaxPinsThisShot(), 9);
r2.computeNext(9);
expect(r2.getMaxPinsThisShot(), 10);
r2.computeNext(10);
expect(r2.getPinsKnockedDown(), 20);
expect(r2.getNbSpares(), 1);
expect(r2.getNbStrike(), 1);
LastRound r3 = LastRound(null, null, null, u, 1, null);
r3.computeNext(10);
r3.computeNext(2);
expect(r3.getMaxPinsThisShot(), 8);
r3.computeNext(8);
expect(r3.getPinsKnockedDown(), 20);
expect(r3.getNbSpares(), 1);
expect(r3.getNbStrike(), 1);
});
}

@ -1,30 +0,0 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:bowl_in/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}
Loading…
Cancel
Save