test: create basic tests #24
5 changed files with 221 additions and 129 deletions
141
integration_test/app_test.dart
Normal file
141
integration_test/app_test.dart
Normal file
|
@ -0,0 +1,141 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:prasule/api/category.dart';
|
||||
import 'package:prasule/api/entry_data.dart';
|
||||
import 'package:prasule/api/wallet.dart';
|
||||
import 'package:prasule/api/wallet_entry.dart';
|
||||
import 'package:prasule/api/wallet_manager.dart';
|
||||
|
||||
import 'package:prasule/main.dart';
|
||||
import 'package:prasule/pw/platformfield.dart';
|
||||
|
||||
void main() {
|
||||
final logger = Logger();
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group("Test classes and API", () {
|
||||
test("Test wallet operations", () async {
|
||||
expect(
|
||||
(await WalletManager.listWallets()).length,
|
||||
equals(0),
|
||||
); // check that there are no other wallets
|
||||
await WalletManager.saveWallet(Wallet.empty);
|
||||
var w = (await WalletManager.listWallets()).firstOrNull;
|
||||
expect(w, isNotNull); // check that the wallet was successfully saved
|
||||
expect(w!.categories.length, equals(1));
|
||||
w.categories.add(
|
||||
WalletCategory(
|
||||
name: "Testing",
|
||||
id: w.nextCategoryId,
|
||||
icon: Icons.abc,
|
||||
color: Colors.orange,
|
||||
),
|
||||
); // create test category
|
||||
final testId = w.nextId;
|
||||
w.entries.add(
|
||||
WalletSingleEntry(
|
||||
data: EntryData(amount: 200, name: "Automated"),
|
||||
type: EntryType.expense,
|
||||
date: DateTime.now(),
|
||||
category: w.categories.last,
|
||||
id: w.nextId,
|
||||
),
|
||||
); // create test entry
|
||||
await WalletManager.saveWallet(w); // save again
|
||||
w = await WalletManager.loadWallet(w.name); // try loading manually
|
||||
final e = w.entries.where((element) => element.id == testId).firstOrNull;
|
||||
expect(
|
||||
e,
|
||||
isNotNull,
|
||||
); // check that the entry was successfully created
|
||||
expect(
|
||||
w.categories.where((element) => element.id == e!.category.id).length,
|
||||
equals(1),
|
||||
); // check that the category exists too
|
||||
|
||||
await WalletManager.deleteWallet(w);
|
||||
expect(
|
||||
(await WalletManager.listWallets()).length,
|
||||
equals(0),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group("Test app functionality:", () {
|
||||
testWidgets('First-time setup', (WidgetTester tester) async {
|
||||
// Delete all data
|
||||
await WalletManager.deleteAllData();
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(
|
||||
const MyApp(
|
||||
locale: Locale('en', 'US'),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
logger.i("Looking for welcome header");
|
||||
expect(find.text('Welcome!'), findsOneWidget);
|
||||
|
||||
// Tap "Next" button
|
||||
await tester.tap(find.text("Next"));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
logger.i("Next view, looking for name+balance fields");
|
||||
|
||||
final firstFields = find.byType(PlatformField);
|
||||
|
||||
expect(firstFields, findsExactly(2));
|
||||
|
||||
logger.i("Entering text");
|
||||
await tester.enterText(find.byType(PlatformField).first, "Debugging");
|
||||
await tester.pumpAndSettle();
|
||||
await tester.enterText(find.byType(PlatformField).last, "100");
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Tap "Next" button
|
||||
await tester.tap(find.text("Next"));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Tap "Finish" button
|
||||
await tester.tap(find.text("Finish"));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(
|
||||
find.byWidgetPredicate(
|
||||
(widget) =>
|
||||
widget is DropdownButton &&
|
||||
((widget as DropdownButton<int>).value ?? -1) == 0,
|
||||
),
|
||||
findsOne,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Test correct rendering of entries',
|
||||
(WidgetTester tester) async {
|
||||
// Delete all data
|
||||
await WalletManager.deleteAllData();
|
||||
expect((await WalletManager.listWallets()).length, equals(0));
|
||||
|
||||
// Create test data
|
||||
final w = Wallet.empty;
|
||||
await w.createTestEntries();
|
||||
expect((await WalletManager.listWallets()).length, equals(1));
|
||||
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(
|
||||
const MyApp(
|
||||
locale: Locale('en', 'US'),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// TODO: better test
|
||||
|
||||
expect(
|
||||
find.byType(ListTile, skipOffstage: false),
|
||||
findsAtLeast(10),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:prasule/api/wallet_manager.dart';
|
||||
|
||||
import 'package:prasule/main.dart';
|
||||
import 'package:prasule/pw/platformfield.dart';
|
||||
|
||||
void main() {
|
||||
final logger = Logger();
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
group("Test Setup screen:", () {
|
||||
testWidgets('First-time setup', (WidgetTester tester) async {
|
||||
// delete all data
|
||||
await WalletManager.deleteAllData();
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(
|
||||
const MyApp(
|
||||
locale: Locale('en', 'US'),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
logger.i("Looking for welcome header");
|
||||
expect(find.text('Welcome!'), findsOneWidget);
|
||||
|
||||
// Tap "Next" button
|
||||
await tester.tap(find.text("Next"));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
logger.i("Next view, looking for name+balance fields");
|
||||
|
||||
final firstFields = find.byType(PlatformField);
|
||||
|
||||
expect(firstFields, findsExactly(2));
|
||||
|
||||
logger.i("Entering text");
|
||||
await tester.enterText(find.byType(PlatformField).first, "Debugging");
|
||||
await tester.pumpAndSettle();
|
||||
await tester.enterText(find.byType(PlatformField).last, "100");
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Tap "Next" button
|
||||
await tester.tap(find.text("Next"));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Tap "Finish" button
|
||||
await tester.tap(find.text("Finish"));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(
|
||||
find.byWidgetPredicate(
|
||||
(widget) =>
|
||||
widget is DropdownButton &&
|
||||
((widget as DropdownButton<int>).value ?? -1) == 0,
|
||||
),
|
||||
findsOne,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,7 +1,11 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:currency_picker/currency_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:prasule/api/category.dart';
|
||||
import 'package:prasule/api/entry_data.dart';
|
||||
import 'package:prasule/api/recurring_entry.dart';
|
||||
import 'package:prasule/api/wallet_entry.dart';
|
||||
import 'package:prasule/api/wallet_manager.dart';
|
||||
|
@ -158,6 +162,19 @@ class Wallet {
|
|||
/// Empty wallet used for placeholders
|
||||
static final Wallet empty = Wallet(
|
||||
name: "Empty",
|
||||
entries: [],
|
||||
recurringEntries: [],
|
||||
categories: [
|
||||
WalletCategory(
|
||||
name: "Default",
|
||||
id: 0,
|
||||
icon: IconData(
|
||||
Icons.payments.codePoint,
|
||||
fontFamily: 'MaterialIcons',
|
||||
),
|
||||
color: Colors.white,
|
||||
)
|
||||
],
|
||||
currency: Currency.from(
|
||||
json: {
|
||||
"code": "USD",
|
||||
|
@ -174,4 +191,66 @@ class Wallet {
|
|||
},
|
||||
),
|
||||
);
|
||||
|
||||
/// Creates test data used for debugging purposes
|
||||
Future<void> createTestEntries() async {
|
||||
entries.clear();
|
||||
recurringEntries.clear();
|
||||
final random = Random();
|
||||
for (var i = 0; i < 30; i++) {
|
||||
entries.add(
|
||||
WalletSingleEntry(
|
||||
data: EntryData(
|
||||
name: "Test Entry #${i + 1}",
|
||||
amount: random.nextInt(20000).toDouble(),
|
||||
),
|
||||
type: (random.nextInt(3) > 0) ? EntryType.expense : EntryType.income,
|
||||
date: DateTime(
|
||||
2023,
|
||||
random.nextInt(12) + 1,
|
||||
random.nextInt(28) + 1,
|
||||
),
|
||||
category: categories[random.nextInt(categories.length)],
|
||||
id: nextId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
logger.d(
|
||||
"Created ${entries.length} regular entries",
|
||||
);
|
||||
|
||||
for (var i = 0; i < 3; i++) {
|
||||
final type = random.nextInt(3);
|
||||
recurringEntries.add(
|
||||
RecurringWalletEntry(
|
||||
data: EntryData(
|
||||
name: "Recurring Entry #${i + 1}",
|
||||
amount: random.nextInt(20000).toDouble(),
|
||||
),
|
||||
type: (random.nextInt(3) > 0) ? EntryType.expense : EntryType.income,
|
||||
date: DateTime(
|
||||
2023,
|
||||
random.nextInt(12) + 1,
|
||||
random.nextInt(28) + 1,
|
||||
),
|
||||
category: categories[random.nextInt(categories.length)],
|
||||
id: nextId,
|
||||
lastRunDate: DateTime.now().subtract(
|
||||
Duration(
|
||||
days: (type > 0) ? 3 : 3 * 31,
|
||||
),
|
||||
),
|
||||
recurType: (type > 0) ? RecurType.day : RecurType.month,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
logger.d(
|
||||
"Created ${recurringEntries.length} recurring entries",
|
||||
);
|
||||
|
||||
// save and reload
|
||||
await WalletManager.saveWallet(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ class WalletManager {
|
|||
// TODO: do something with unreadable wallets
|
||||
}
|
||||
}
|
||||
logger.i(wallets.length);
|
||||
return wallets;
|
||||
}
|
||||
|
||||
|
@ -37,7 +36,6 @@ class WalletManager {
|
|||
}
|
||||
|
||||
for (final entry in path.listSync()) {
|
||||
if (!entry.path.endsWith(".json")) return; // only delete wallet files
|
||||
logger.d("Deleting ${entry.path}");
|
||||
entry.deleteSync();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// ignore_for_file: inference_failure_on_function_invocation
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
@ -16,7 +15,6 @@ import 'package:intl/date_symbol_data_local.dart';
|
|||
import 'package:intl/intl.dart';
|
||||
import 'package:prasule/api/category.dart';
|
||||
import 'package:prasule/api/entry_data.dart';
|
||||
import 'package:prasule/api/recurring_entry.dart';
|
||||
import 'package:prasule/api/wallet.dart';
|
||||
import 'package:prasule/api/wallet_entry.dart';
|
||||
import 'package:prasule/api/wallet_manager.dart';
|
||||
|
@ -88,70 +86,7 @@ class _HomeViewState extends State<HomeView> {
|
|||
onTap: () {
|
||||
// debug option to quickly fill a wallet with data
|
||||
if (selectedWallet == null) return;
|
||||
selectedWallet!.entries.clear();
|
||||
selectedWallet!.recurringEntries.clear();
|
||||
final random = Random();
|
||||
for (var i = 0; i < 30; i++) {
|
||||
selectedWallet!.entries.add(
|
||||
WalletSingleEntry(
|
||||
data: EntryData(
|
||||
name: "Test Entry #${i + 1}",
|
||||
amount: random.nextInt(20000).toDouble(),
|
||||
),
|
||||
type: (random.nextInt(3) > 0)
|
||||
? EntryType.expense
|
||||
: EntryType.income,
|
||||
date: DateTime(
|
||||
2023,
|
||||
random.nextInt(12) + 1,
|
||||
random.nextInt(28) + 1,
|
||||
),
|
||||
category: selectedWallet!.categories[
|
||||
random.nextInt(selectedWallet!.categories.length)],
|
||||
id: selectedWallet!.nextId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
logger.d(
|
||||
"Created ${selectedWallet!.entries.length} regular entries",
|
||||
);
|
||||
|
||||
for (var i = 0; i < 3; i++) {
|
||||
final type = random.nextInt(3);
|
||||
selectedWallet!.recurringEntries.add(
|
||||
RecurringWalletEntry(
|
||||
data: EntryData(
|
||||
name: "Recurring Entry #${i + 1}",
|
||||
amount: random.nextInt(20000).toDouble(),
|
||||
),
|
||||
type: (random.nextInt(3) > 0)
|
||||
? EntryType.expense
|
||||
: EntryType.income,
|
||||
date: DateTime(
|
||||
2023,
|
||||
random.nextInt(12) + 1,
|
||||
random.nextInt(28) + 1,
|
||||
),
|
||||
category: selectedWallet!.categories[
|
||||
random.nextInt(selectedWallet!.categories.length)],
|
||||
id: selectedWallet!.nextId,
|
||||
lastRunDate: DateTime.now().subtract(
|
||||
Duration(
|
||||
days: (type > 0) ? 3 : 3 * 31,
|
||||
),
|
||||
),
|
||||
recurType: (type > 0) ? RecurType.day : RecurType.month,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
logger.d(
|
||||
"Created ${selectedWallet!.recurringEntries.length} recurring entries",
|
||||
);
|
||||
|
||||
// save and reload
|
||||
WalletManager.saveWallet(selectedWallet!).then((value) {
|
||||
selectedWallet!.createTestEntries().then((_) {
|
||||
Navigator.of(context).pushReplacement(
|
||||
platformRoute(
|
||||
(p0) => const HomeView(),
|
||||
|
|
Loading…
Reference in a new issue