Began to make unit tests + started to document CRUD service
This commit is contained in:
parent
8de7946370
commit
a3e09d1ca7
|
@ -9,15 +9,19 @@ import 'package:path/path.dart' show join;
|
|||
|
||||
const String dbName = "TetraStats.db";
|
||||
|
||||
/// Base class for CRUD services. Contains basic functions
|
||||
class DB {
|
||||
Database? _db;
|
||||
|
||||
/// Handles opening of DB and creates tables if they not exist
|
||||
Future<void> open() async {
|
||||
if (_db != null) {
|
||||
// in order to not open DB multiple times
|
||||
throw DatabaseAlreadyOpen();
|
||||
}
|
||||
try {
|
||||
String dbPath;
|
||||
if (kIsWeb) {
|
||||
if (kIsWeb) { // i hate web
|
||||
dbPath = dbName;
|
||||
} else {
|
||||
final docsPath = await getApplicationDocumentsDirectory();
|
||||
|
@ -34,6 +38,7 @@ class DB {
|
|||
}
|
||||
}
|
||||
|
||||
/// Handles closing of DB
|
||||
Future<void> close() async {
|
||||
final db = _db;
|
||||
if (db == null) {
|
||||
|
@ -44,6 +49,7 @@ class DB {
|
|||
}
|
||||
}
|
||||
|
||||
/// if we need instance of our DB, it will return it.
|
||||
Database getDatabaseOrThrow() {
|
||||
final db = _db;
|
||||
if (db == null) {
|
||||
|
@ -53,6 +59,7 @@ class DB {
|
|||
}
|
||||
}
|
||||
|
||||
/// You can never be too sure. Although we can be 100% sure, that DB is open after executing that function
|
||||
Future<void> ensureDbIsOpen() async {
|
||||
try {
|
||||
await open();
|
||||
|
@ -61,6 +68,7 @@ class DB {
|
|||
}
|
||||
}
|
||||
|
||||
/// Executes VACUUM command for our DB and returns number of bytes, that was saved with this operation
|
||||
Future<int> compressDB() async{
|
||||
await ensureDbIsOpen();
|
||||
final db = getDatabaseOrThrow();
|
||||
|
|
|
@ -27,6 +27,7 @@ const String endContext2 = "endContext2";
|
|||
const String statesCol = "jsonStates";
|
||||
const String player1id = "player1id";
|
||||
const String player2id = "player2id";
|
||||
/// Table, that store players data, their stats and some moments of time
|
||||
const String createTetrioUsersTable = '''
|
||||
CREATE TABLE IF NOT EXISTS "tetrioUsers" (
|
||||
"id" TEXT UNIQUE,
|
||||
|
@ -34,12 +35,14 @@ const String createTetrioUsersTable = '''
|
|||
"jsonStates" TEXT,
|
||||
PRIMARY KEY("id")
|
||||
);''';
|
||||
/// Table, that store ids of players we need keep track of
|
||||
const String createTetrioUsersToTrack = '''
|
||||
CREATE TABLE IF NOT EXISTS "tetrioUsersToTrack" (
|
||||
"id" TEXT NOT NULL UNIQUE,
|
||||
PRIMARY KEY("ID")
|
||||
)
|
||||
''';
|
||||
/// Table of Tetra League matches. Each match corresponds with their own players and end contexts
|
||||
const String createTetrioTLRecordsTable = '''
|
||||
CREATE TABLE IF NOT EXISTS "tetrioAlphaLeagueMathces" (
|
||||
"id" TEXT NOT NULL UNIQUE,
|
||||
|
@ -52,7 +55,7 @@ const String createTetrioTLRecordsTable = '''
|
|||
PRIMARY KEY("id")
|
||||
)
|
||||
''';
|
||||
|
||||
/// Table, that contains results of replay analysis in order to not analyze it more, than one time.
|
||||
const String createTetrioTLReplayStats = '''
|
||||
CREATE TABLE IF NOT EXISTS "tetrioTLReplayStats" (
|
||||
"id" TEXT NOT NULL,
|
||||
|
@ -64,15 +67,19 @@ const String createTetrioTLReplayStats = '''
|
|||
|
||||
class TetrioService extends DB {
|
||||
Map<String, List<TetrioPlayer>> _players = {};
|
||||
|
||||
// I'm trying to send as less requests, as possible, so i'm caching the results of those requests.
|
||||
// Usually those maps looks like this: {"cached_until_unix_milliseconds": Object}
|
||||
final Map<String, TetrioPlayer> _playersCache = {};
|
||||
final Map<String, Map<String, dynamic>> _recordsCache = {};
|
||||
final Map<String, dynamic> _replaysCache = {};
|
||||
final Map<String, dynamic> _replaysCache = {}; // the only one is different: {"replayID": [replayString, replayBytes]}
|
||||
final Map<String, TetrioPlayersLeaderboard> _leaderboardsCache = {};
|
||||
final Map<String, List<News>> _newsCache = {};
|
||||
final Map<String, Map<String, double?>> _topTRcache = {};
|
||||
final Map<String, TetraLeagueAlphaStream> _tlStreamsCache = {}; // i'm trying to respect oskware api It should look something like {"cached_until": TetrioPlayer}
|
||||
final client = UserAgentClient("Tetra Stats v${packageInfo.version} (dm @dan63047 if someone abuse that software)", http.Client());
|
||||
//final client = UserAgentClient("Kagari-chan loves osk (Tetra Stats dev build)", http.Client());
|
||||
final Map<String, TetraLeagueAlphaStream> _tlStreamsCache = {};
|
||||
/// Thing, that sends every request to the API endpoints
|
||||
final client = kDebugMode ? UserAgentClient("Kagari-chan loves osk (Tetra Stats dev build)", http.Client()) : UserAgentClient("Tetra Stats v${packageInfo.version} (dm @dan63047 if someone abuse that software)", http.Client());
|
||||
/// We should have only one instanse of this service
|
||||
static final TetrioService _shared = TetrioService._sharedInstance();
|
||||
factory TetrioService() => _shared;
|
||||
late final StreamController<Map<String, List<TetrioPlayer>>> _tetrioStreamController;
|
||||
|
@ -90,6 +97,7 @@ class TetrioService extends DB {
|
|||
|
||||
Stream<Map<String, List<TetrioPlayer>>> get allPlayers => _tetrioStreamController.stream;
|
||||
|
||||
/// Loading and sending to the stream everyone.
|
||||
Future<void> _loadPlayers() async {
|
||||
final allPlayers = await getAllPlayers();
|
||||
try{
|
||||
|
@ -101,6 +109,8 @@ class TetrioService extends DB {
|
|||
_tetrioStreamController.add(_players);
|
||||
}
|
||||
|
||||
/// Removes player entry from tetrioUsersTable with given [id].
|
||||
/// Can throw an error is player with this id is not exist
|
||||
Future<void> deletePlayer(String id) async {
|
||||
await ensureDbIsOpen();
|
||||
final db = getDatabaseOrThrow();
|
||||
|
@ -113,8 +123,10 @@ class TetrioService extends DB {
|
|||
}
|
||||
}
|
||||
|
||||
/// Gets nickname from database or requests it from API if missing.
|
||||
/// Throws an exception if user not exist or request failed.
|
||||
Future<String> getNicknameByID(String id) async {
|
||||
if (id.length <= 16) return id;
|
||||
if (id.length <= 16) return id; // nicknames can be up to 16 symbols in length, that's how i'm differentiate nickname from ids
|
||||
try{
|
||||
return await getPlayer(id).then((value) => value.last.username);
|
||||
} catch (e){
|
||||
|
@ -122,15 +134,18 @@ class TetrioService extends DB {
|
|||
}
|
||||
}
|
||||
|
||||
/// Puts results of replay analysis into a tetrioTLReplayStatsTable
|
||||
Future<void> saveReplayStats(ReplayData replay) async {
|
||||
await ensureDbIsOpen();
|
||||
final db = getDatabaseOrThrow();
|
||||
db.insert(tetrioTLReplayStatsTable, {idCol: replay.id, "data": jsonEncode(replay.toJson())});
|
||||
}
|
||||
|
||||
/// Downloads replay from inoue (szy API). Requiers [replayID]. If request have
|
||||
/// different from 200 statusCode, it will throw an excepction. Returns list, that contains same replay
|
||||
/// as string and as binary.
|
||||
Future<List<dynamic>> szyGetReplay(String replayID) async {
|
||||
try{
|
||||
// read from cache
|
||||
try{ // read from cache
|
||||
var cached = _replaysCache.entries.firstWhere((element) => element.key == replayID);
|
||||
return cached.value;
|
||||
}catch (e){
|
||||
|
@ -138,13 +153,13 @@ class TetrioService extends DB {
|
|||
}
|
||||
|
||||
Uri url;
|
||||
if (kIsWeb) {
|
||||
if (kIsWeb) { // Web version sends every request through my php script at the same domain, where Tetra Stats located because of CORS
|
||||
url = Uri.https('ts.dan63.by', 'oskware_bridge.php', {"endpoint": "tetrioReplay", "replayid": replayID});
|
||||
} else {
|
||||
} else { // Actually going to hit inoue
|
||||
url = Uri.https('inoue.szy.lol', '/api/replay/$replayID');
|
||||
}
|
||||
|
||||
// trying to obtain replay from download directory first
|
||||
// Trying to obtain replay from download directory first
|
||||
if (!kIsWeb){ // can't obtain download directory on web
|
||||
var downloadPath = await getDownloadsDirectory();
|
||||
downloadPath ??= Platform.isAndroid ? Directory("/storage/emulated/0/Download") : await getApplicationDocumentsDirectory();
|
||||
|
@ -158,7 +173,7 @@ class TetrioService extends DB {
|
|||
switch (response.statusCode) {
|
||||
case 200:
|
||||
developer.log("szyDownload: Replay downloaded", name: "services/tetrio_crud", error: response.statusCode);
|
||||
_replaysCache[replayID] = [response.body, response.bodyBytes];
|
||||
_replaysCache[replayID] = [response.body, response.bodyBytes]; // Puts results into the cache
|
||||
return [response.body, response.bodyBytes];
|
||||
case 404:
|
||||
throw SzyNotFound();
|
||||
|
@ -829,7 +844,6 @@ class TetrioService extends DB {
|
|||
final db = getDatabaseOrThrow();
|
||||
final players = await db.query(tetrioUsersTable);
|
||||
Map<String, List<TetrioPlayer>> data = {};
|
||||
//developer.log("getAllPlayers: $players", name: "services/tetrio_crud");
|
||||
return players.map((row) {
|
||||
// what the fuck am i doing here?
|
||||
var test = json.decode(row['jsonStates'] as String);
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
extension MinusOneSecond on Duration{
|
||||
static const Duration minusOneSecond = Duration(seconds: -1);
|
||||
}
|
|
@ -196,12 +196,10 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
if (uniqueTL.isNotEmpty && uniqueTL.last != element.tlSeason1) uniqueTL.add(element.tlSeason1);
|
||||
if (uniqueTL.isEmpty) uniqueTL.add(element.tlSeason1);
|
||||
}
|
||||
try{
|
||||
compareWith = uniqueTL.toList()[uniqueTL.length - 2]; // Also i need previous Tetra League State for comparison
|
||||
}on RangeError {
|
||||
compareWith = null; // If can't acess it - ok then
|
||||
}
|
||||
chartsData = <DropdownMenuItem<List<FlSpot>>>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid
|
||||
// Also i need previous Tetra League State for comparison if avaliable
|
||||
compareWith = uniqueTL.length >= 2 ? uniqueTL.toList().elementAtOrNull(uniqueTL.length - 2) : null;
|
||||
|
||||
chartsData = <DropdownMenuItem<List<FlSpot>>>[ // Dumping charts data into dropdown menu items, while cheking if every entry is valid
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.rating)], child: Text(t.statCellNum.tr)),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.glicko!)], child: const Text("Glicko")),
|
||||
DropdownMenuItem(value: [for (var tl in uniqueTL) if (tl.gamesPlayed > 9) FlSpot(tl.timestamp.millisecondsSinceEpoch.toDouble(), tl.rd!)], child: const Text("Rating Deviation")),
|
||||
|
@ -311,8 +309,8 @@ class _MainState extends State<MainView> with TickerProviderStateMixin {
|
|||
case ConnectionState.done:
|
||||
//bool bigScreen = MediaQuery.of(context).size.width > 1024;
|
||||
if (snapshot.hasData) {
|
||||
List<RecordSingle> sprintRuns = snapshot.data![1]['sprint'];
|
||||
List<RecordSingle> blitzRuns = snapshot.data![1]['blitz'];
|
||||
List<dynamic> sprintRuns = snapshot.data![1]['sprint'];
|
||||
List<dynamic> blitzRuns = snapshot.data![1]['blitz'];
|
||||
return RefreshIndicator(
|
||||
onRefresh: () {
|
||||
return Future(() => changePlayer(snapshot.data![0].userId));
|
||||
|
|
|
@ -271,7 +271,7 @@ class UserThingy extends StatelessWidget {
|
|||
playerStatLabel: t.statCellNum.hoursPlayed,
|
||||
isScreenBig: bigScreen,
|
||||
alertTitle: t.exactGametime,
|
||||
alertWidgets: [Text(player.gameTime.toString(), style: TextStyle(fontFamily: "Eurostile Round Extended"),)],
|
||||
alertWidgets: [Text(player.gameTime.toString(), style: const TextStyle(fontFamily: "Eurostile Round Extended"),)],
|
||||
higherIsBetter: true,),
|
||||
if (player.gamesPlayed >= 0)
|
||||
StatCellNum(
|
||||
|
|
168
pubspec.lock
168
pubspec.lock
|
@ -1,6 +1,22 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "64.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -81,6 +97,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.7.2"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -301,6 +325,22 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
go_router:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -317,6 +357,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -341,6 +389,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.18.1"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -413,6 +469,30 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
package_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -613,6 +693,38 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -634,6 +746,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.28.0"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.10.12"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -746,6 +874,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.24.9"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -754,6 +890,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.1"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.9"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -858,6 +1002,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -874,6 +1026,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -49,6 +49,7 @@ dev_dependencies:
|
|||
sdk: flutter
|
||||
flutter_lints: ^3.0.1
|
||||
flutter_launcher_icons: "^0.13.1"
|
||||
test: ^1.24.9
|
||||
|
||||
|
||||
flutter_launcher_icons:
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||
import 'package:sqflite_common_ffi_web/sqflite_ffi_web.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:tetra_stats/data_objects/tetrio.dart';
|
||||
import 'package:tetra_stats/services/crud_exceptions.dart';
|
||||
import 'package:tetra_stats/services/tetrio_crud.dart';
|
||||
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
DartPluginRegistrant.ensureInitialized();
|
||||
if (kIsWeb) {
|
||||
sqfliteFfiInit();
|
||||
databaseFactory = databaseFactoryFfiWeb;
|
||||
} else if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
|
||||
sqfliteFfiInit();
|
||||
databaseFactory = databaseFactoryFfi;
|
||||
}
|
||||
test("Initialize TetrioServise", () async {
|
||||
await TetrioService().open();
|
||||
}, skip: true); // a fucking MissingPluginException how does that even happening?
|
||||
// i guess i will be unable to test iteractions with DB
|
||||
|
||||
group("Test fetchPlayer with different players", () {
|
||||
test("dan63047 (user who have activity in tetra league)", () async {
|
||||
TetrioPlayer dan63047 = await TetrioService().fetchPlayer("6098518e3d5155e6ec429cdc");
|
||||
expect(dan63047.userId, "6098518e3d5155e6ec429cdc");
|
||||
expect(dan63047.registrationTime != null, true);
|
||||
expect(dan63047.avatarRevision != null, true);
|
||||
expect(dan63047.connections != null, true);
|
||||
expect(dan63047.role, "user");
|
||||
expect(dan63047.distinguishment, null); // imagine if that one fails one day lol
|
||||
expect(dan63047.tlSeason1.glicko != null, true);
|
||||
//expect(dan63047.tlSeason1.rank != "z", true); lol
|
||||
expect(dan63047.tlSeason1.percentileRank != "z", true);
|
||||
expect(dan63047.tlSeason1.rating > -1, true);
|
||||
expect(dan63047.tlSeason1.gamesPlayed > 9, true);
|
||||
expect(dan63047.tlSeason1.gamesWon > 0, true);
|
||||
//expect(dan63047.tlSeason1.standing, -1);
|
||||
//expect(dan63047.tlSeason1.standingLocal, -1);
|
||||
expect(dan63047.tlSeason1.apm != null, true);
|
||||
expect(dan63047.tlSeason1.pps != null, true);
|
||||
expect(dan63047.tlSeason1.vs != null, true);
|
||||
expect(dan63047.tlSeason1.nerdStats != null, true);
|
||||
expect(dan63047.tlSeason1.estTr != null, true);
|
||||
expect(dan63047.tlSeason1.esttracc != null, true);
|
||||
expect(dan63047.tlSeason1.playstyle != null, true);
|
||||
});
|
||||
test("osk (sysop who have activity in tetra league)", () async {
|
||||
TetrioPlayer osk = await TetrioService().fetchPlayer("5e32fc85ab319c2ab1beb07c");
|
||||
expect(osk.userId, "5e32fc85ab319c2ab1beb07c");
|
||||
expect(osk.registrationTime, null);
|
||||
expect(osk.country, "XM");
|
||||
expect(osk.avatarRevision != null, true);
|
||||
expect(osk.bannerRevision != null, true);
|
||||
expect(osk.connections != null, true);
|
||||
expect(osk.verified, true);
|
||||
expect(osk.role, "sysop");
|
||||
expect(osk.distinguishment != null, true);
|
||||
expect(osk.tlSeason1.glicko != null, true);
|
||||
expect(osk.tlSeason1.glicko != null, true);
|
||||
expect(osk.tlSeason1.rank == "z", true);
|
||||
expect(osk.tlSeason1.percentileRank != "z", true);
|
||||
expect(osk.tlSeason1.rating > -1, true);
|
||||
expect(osk.tlSeason1.gamesPlayed > 9, true);
|
||||
expect(osk.tlSeason1.gamesWon > 0, true);
|
||||
expect(osk.tlSeason1.standing, -1);
|
||||
expect(osk.tlSeason1.standingLocal, -1);
|
||||
expect(osk.tlSeason1.apm != null, true);
|
||||
expect(osk.tlSeason1.pps != null, true);
|
||||
expect(osk.tlSeason1.vs != null, true);
|
||||
expect(osk.tlSeason1.nerdStats != null, true);
|
||||
expect(osk.tlSeason1.estTr != null, true);
|
||||
expect(osk.tlSeason1.esttracc != null, true);
|
||||
expect(osk.tlSeason1.playstyle != null, true);
|
||||
});
|
||||
test("kagari (sysop who have zero activity)", () async {
|
||||
TetrioPlayer kagari = await TetrioService().fetchPlayer("5e331c3ce24a5a3e258f7a1b");
|
||||
expect(kagari.userId, "5e331c3ce24a5a3e258f7a1b");
|
||||
expect(kagari.registrationTime, null);
|
||||
expect(kagari.country, "XM");
|
||||
expect(kagari.xp, 0);
|
||||
expect(kagari.gamesPlayed, -1);
|
||||
expect(kagari.gamesWon, -1);
|
||||
expect(kagari.gameTime, const Duration(seconds: -1));
|
||||
expect(kagari.avatarRevision != null, true);
|
||||
expect(kagari.bannerRevision != null, true);
|
||||
expect(kagari.connections, null);
|
||||
expect(kagari.verified, true);
|
||||
expect(kagari.distinguishment != null, true);
|
||||
expect(kagari.distinguishment!.detail, "kagarin");
|
||||
expect(kagari.friendCount, 1);
|
||||
expect(kagari.tlSeason1.glicko, null);
|
||||
expect(kagari.tlSeason1.rank, "z");
|
||||
expect(kagari.tlSeason1.percentileRank, "z");
|
||||
expect(kagari.tlSeason1.rating, -1);
|
||||
expect(kagari.tlSeason1.decaying, false);
|
||||
expect(kagari.tlSeason1.gamesPlayed, 0);
|
||||
expect(kagari.tlSeason1.gamesWon, 0);
|
||||
expect(kagari.tlSeason1.standing, -1);
|
||||
expect(kagari.tlSeason1.standingLocal, -1);
|
||||
expect(kagari.tlSeason1.apm, null);
|
||||
expect(kagari.tlSeason1.pps, null);
|
||||
expect(kagari.tlSeason1.vs, null);
|
||||
expect(kagari.tlSeason1.nerdStats, null);
|
||||
expect(kagari.tlSeason1.estTr, null);
|
||||
expect(kagari.tlSeason1.esttracc, null);
|
||||
expect(kagari.tlSeason1.playstyle, null);
|
||||
});
|
||||
test("furry (banned account)", () async {
|
||||
TetrioPlayer furry = await TetrioService().fetchPlayer("5eea0ff69a1ba76c20347086");
|
||||
expect(furry.userId, "5eea0ff69a1ba76c20347086");
|
||||
expect(furry.registrationTime, DateTime.parse("2020-06-17T12:43:34.790Z"));
|
||||
expect(furry.role, "banned");
|
||||
expect(furry.badges.isEmpty, true);
|
||||
expect(furry.badstanding, false);
|
||||
expect(furry.xp, 0);
|
||||
expect(furry.supporterTier, 0);
|
||||
expect(furry.verified, false);
|
||||
expect(furry.connections, null);
|
||||
expect(furry.gamesPlayed, 0);
|
||||
expect(furry.gamesWon, 0);
|
||||
expect(furry.gameTime, Duration.zero);
|
||||
expect(furry.tlSeason1.glicko, null);
|
||||
expect(furry.tlSeason1.rank, "z");
|
||||
expect(furry.tlSeason1.percentileRank, "z");
|
||||
expect(furry.tlSeason1.rating, -1);
|
||||
expect(furry.tlSeason1.decaying, false);
|
||||
expect(furry.tlSeason1.gamesPlayed, 0);
|
||||
expect(furry.tlSeason1.gamesWon, 0);
|
||||
expect(furry.tlSeason1.standing, -1);
|
||||
expect(furry.tlSeason1.standingLocal, -1);
|
||||
expect(furry.tlSeason1.apm, null);
|
||||
expect(furry.tlSeason1.pps, null);
|
||||
expect(furry.tlSeason1.vs, null);
|
||||
expect(furry.tlSeason1.nerdStats, null);
|
||||
expect(furry.tlSeason1.estTr, null);
|
||||
expect(furry.tlSeason1.esttracc, null);
|
||||
expect(furry.tlSeason1.playstyle, null);
|
||||
});
|
||||
test("oskwarefan (anon account)", () async {
|
||||
TetrioPlayer oskwarefan = await TetrioService().fetchPlayer("646cb8273e887a054d64febe");
|
||||
expect(oskwarefan.userId, "646cb8273e887a054d64febe");
|
||||
expect(oskwarefan.registrationTime, DateTime.parse("2023-05-23T12:57:11.481Z"));
|
||||
expect(oskwarefan.role, "anon");
|
||||
expect(oskwarefan.xp > 0, true);
|
||||
expect(oskwarefan.gamesPlayed > -1, true);
|
||||
expect(oskwarefan.gamesWon > -1, true);
|
||||
expect(oskwarefan.gameTime.isNegative, false);
|
||||
expect(oskwarefan.country, null);
|
||||
expect(oskwarefan.verified, false);
|
||||
expect(oskwarefan.connections, null);
|
||||
expect(oskwarefan.friendCount, 0);
|
||||
expect(oskwarefan.tlSeason1.glicko, null);
|
||||
expect(oskwarefan.tlSeason1.rank, "z");
|
||||
expect(oskwarefan.tlSeason1.percentileRank, "z");
|
||||
expect(oskwarefan.tlSeason1.rating, -1);
|
||||
expect(oskwarefan.tlSeason1.decaying, true); // ??? why true?
|
||||
expect(oskwarefan.tlSeason1.gamesPlayed, 0);
|
||||
expect(oskwarefan.tlSeason1.gamesWon, 0);
|
||||
expect(oskwarefan.tlSeason1.standing, -1);
|
||||
expect(oskwarefan.tlSeason1.standingLocal, -1);
|
||||
expect(oskwarefan.tlSeason1.apm, null);
|
||||
expect(oskwarefan.tlSeason1.pps, null);
|
||||
expect(oskwarefan.tlSeason1.vs, null);
|
||||
expect(oskwarefan.tlSeason1.nerdStats, null);
|
||||
expect(oskwarefan.tlSeason1.estTr, null);
|
||||
expect(oskwarefan.tlSeason1.esttracc, null);
|
||||
expect(oskwarefan.tlSeason1.playstyle, null);
|
||||
});
|
||||
|
||||
test("not existing account", () async {
|
||||
var future = TetrioService().fetchPlayer("hasdbashdbs");
|
||||
await expectLater(future, throwsA(isA<TetrioPlayerNotExist>()));
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue