Basic framework #8
40
finlog_app/fluttery/lib/preferences/preferences.dart
Normal file
40
finlog_app/fluttery/lib/preferences/preferences.dart
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import 'package:fluttery/fluttery.dart';
|
||||||
|
|
||||||
|
/// providing methods for managing persistent storage of key-value pairs.
|
||||||
|
abstract class Preferences implements Service {
|
||||||
|
/// Stores a string value with the given [key].
|
||||||
|
Future<void> setString(String key, String value);
|
||||||
|
|
||||||
|
/// Retrieves the string value associated with the given [key].
|
||||||
|
Future<String?> getString(String key);
|
||||||
|
|
||||||
|
/// Stores an integer value with the given [key].
|
||||||
|
Future<void> setInt(String key, int value);
|
||||||
|
|
||||||
|
/// Retrieves the integer value associated with the given [key].
|
||||||
|
Future<int?> getInt(String key);
|
||||||
|
|
||||||
|
/// Stores a boolean value with the given [key].
|
||||||
|
Future<void> setBool(String key, bool value);
|
||||||
|
|
||||||
|
/// Retrieves the boolean value associated with the given [key].
|
||||||
|
Future<bool?> getBool(String key);
|
||||||
|
|
||||||
|
/// Stores a double value with the given [key].
|
||||||
|
Future<void> setDouble(String key, double value);
|
||||||
|
|
||||||
|
/// Retrieves the double value associated with the given [key].
|
||||||
|
Future<double?> getDouble(String key);
|
||||||
|
|
||||||
|
/// Stores a list of strings with the given [key].
|
||||||
|
Future<void> setStringList(String key, List<String> value);
|
||||||
|
|
||||||
|
/// Retrieves the list of strings associated with the given [key].
|
||||||
|
Future<List<String>?> getStringList(String key);
|
||||||
|
|
||||||
|
/// Removes the key-value pair associated with the given [key].
|
||||||
|
Future<void> remove(String key);
|
||||||
|
|
||||||
|
/// Clears all key-value pairs in the preferences.
|
||||||
|
Future<void> clear();
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fluttery/preferences/preferences.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
class PreferencesImpl implements Preferences {
|
||||||
|
final SharedPreferences _prefs;
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
PreferencesImpl({required SharedPreferences instance}) : _prefs = instance;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setString(String key, String value) async {
|
||||||
|
await _prefs.setString(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String?> getString(String key) async {
|
||||||
|
return _prefs.getString(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setInt(String key, int value) async {
|
||||||
|
await _prefs.setInt(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<int?> getInt(String key) async {
|
||||||
|
return _prefs.getInt(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setBool(String key, bool value) async {
|
||||||
|
await _prefs.setBool(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool?> getBool(String key) async {
|
||||||
|
return _prefs.getBool(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setDouble(String key, double value) async {
|
||||||
|
await _prefs.setDouble(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<double?> getDouble(String key) async {
|
||||||
|
return _prefs.getDouble(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> setStringList(String key, List<String> value) async {
|
||||||
|
await _prefs.setStringList(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<String>?> getStringList(String key) async {
|
||||||
|
return _prefs.getStringList(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> remove(String key) async {
|
||||||
|
await _prefs.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> clear() async {
|
||||||
|
await _prefs.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ dependencies:
|
|||||||
kiwi: ^5.0.1
|
kiwi: ^5.0.1
|
||||||
logging: ^1.3.0
|
logging: ^1.3.0
|
||||||
mocktail: ^1.0.4
|
mocktail: ^1.0.4
|
||||||
|
shared_preferences: ^2.5.3
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
177
finlog_app/fluttery/test/preferences/preferences_test.dart
Normal file
177
finlog_app/fluttery/test/preferences/preferences_test.dart
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:fluttery/src/preferences/preferences_impl.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
late PreferencesImpl preferences;
|
||||||
|
|
||||||
|
setUp(() async {
|
||||||
|
// Clear any existing data and set up a fresh in-memory instance
|
||||||
|
SharedPreferences.setMockInitialValues({});
|
||||||
|
|
||||||
|
// Create preferences instance that will use the real SharedPreferences
|
||||||
|
// but with in-memory storage for testing
|
||||||
|
final sharedInstance = await SharedPreferences.getInstance();
|
||||||
|
preferences = PreferencesImpl(instance: sharedInstance);
|
||||||
|
|
||||||
|
// Give time for initialization
|
||||||
|
await Future.delayed(Duration.zero);
|
||||||
|
});
|
||||||
|
|
||||||
|
group('PreferencesImpl Tests', () {
|
||||||
|
test('setString and getString work with real implementation', () async {
|
||||||
|
const key = 'testKey';
|
||||||
|
const value = 'testValue';
|
||||||
|
|
||||||
|
await preferences.setString(key, value);
|
||||||
|
final result = await preferences.getString(key);
|
||||||
|
|
||||||
|
expect(result, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setInt and getInt work with real implementation', () async {
|
||||||
|
const key = 'testKey';
|
||||||
|
const value = 42;
|
||||||
|
|
||||||
|
await preferences.setInt(key, value);
|
||||||
|
final result = await preferences.getInt(key);
|
||||||
|
|
||||||
|
expect(result, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setBool and getBool work with real implementation', () async {
|
||||||
|
const key = 'testKey';
|
||||||
|
const value = true;
|
||||||
|
|
||||||
|
await preferences.setBool(key, value);
|
||||||
|
final result = await preferences.getBool(key);
|
||||||
|
|
||||||
|
expect(result, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('setDouble and getDouble work with real implementation', () async {
|
||||||
|
const key = 'testKey';
|
||||||
|
const value = 3.14;
|
||||||
|
|
||||||
|
await preferences.setDouble(key, value);
|
||||||
|
final result = await preferences.getDouble(key);
|
||||||
|
|
||||||
|
expect(result, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'setStringList and getStringList work with real implementation',
|
||||||
|
() async {
|
||||||
|
const key = 'testKey';
|
||||||
|
const value = ['one', 'two', 'three'];
|
||||||
|
|
||||||
|
await preferences.setStringList(key, value);
|
||||||
|
final result = await preferences.getStringList(key);
|
||||||
|
|
||||||
|
expect(result, value);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test('remove deletes key-value pair', () async {
|
||||||
|
const key = 'testKey';
|
||||||
|
const value = 'testValue';
|
||||||
|
|
||||||
|
// Set a value first
|
||||||
|
await preferences.setString(key, value);
|
||||||
|
expect(await preferences.getString(key), value);
|
||||||
|
|
||||||
|
// Remove it
|
||||||
|
await preferences.remove(key);
|
||||||
|
final result = await preferences.getString(key);
|
||||||
|
|
||||||
|
expect(result, isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('clear removes all data', () async {
|
||||||
|
// Set multiple values
|
||||||
|
await preferences.setString('key1', 'value1');
|
||||||
|
await preferences.setInt('key2', 42);
|
||||||
|
await preferences.setBool('key3', true);
|
||||||
|
|
||||||
|
// Verify they exist
|
||||||
|
expect(await preferences.getString('key1'), 'value1');
|
||||||
|
expect(await preferences.getInt('key2'), 42);
|
||||||
|
expect(await preferences.getBool('key3'), true);
|
||||||
|
|
||||||
|
// Clear all
|
||||||
|
await preferences.clear();
|
||||||
|
|
||||||
|
// Verify they're gone
|
||||||
|
expect(await preferences.getString('key1'), isNull);
|
||||||
|
expect(await preferences.getInt('key2'), isNull);
|
||||||
|
expect(await preferences.getBool('key3'), isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getting non-existent keys returns null', () async {
|
||||||
|
expect(await preferences.getString('nonExistent'), isNull);
|
||||||
|
expect(await preferences.getInt('nonExistent'), isNull);
|
||||||
|
expect(await preferences.getBool('nonExistent'), isNull);
|
||||||
|
expect(await preferences.getDouble('nonExistent'), isNull);
|
||||||
|
expect(await preferences.getStringList('nonExistent'), isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('can overwrite existing values of the same type', () async {
|
||||||
|
const key = 'testKey';
|
||||||
|
const initialValue = 'initialValue';
|
||||||
|
const newValue = 'newValue';
|
||||||
|
|
||||||
|
await preferences.setString(key, initialValue);
|
||||||
|
expect(await preferences.getString(key), initialValue);
|
||||||
|
|
||||||
|
await preferences.setString(key, newValue);
|
||||||
|
expect(await preferences.getString(key), newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'different keys can store different data types simultaneously',
|
||||||
|
() async {
|
||||||
|
await preferences.setString('stringKey', 'value');
|
||||||
|
await preferences.setInt('intKey', 42);
|
||||||
|
await preferences.setBool('boolKey', true);
|
||||||
|
await preferences.setDouble('doubleKey', 3.14);
|
||||||
|
await preferences.setStringList('listKey', ['a', 'b', 'c']);
|
||||||
|
|
||||||
|
expect(await preferences.getString('stringKey'), 'value');
|
||||||
|
expect(await preferences.getInt('intKey'), 42);
|
||||||
|
expect(await preferences.getBool('boolKey'), true);
|
||||||
|
expect(await preferences.getDouble('doubleKey'), 3.14);
|
||||||
|
expect(await preferences.getStringList('listKey'), ['a', 'b', 'c']);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test('values can be overwritten with different data types', () async {
|
||||||
|
const key = 'testKey';
|
||||||
|
|
||||||
|
// Store a string value
|
||||||
|
await preferences.setString(key, 'stringValue');
|
||||||
|
expect(await preferences.getString(key), 'stringValue');
|
||||||
|
|
||||||
|
// Overwrite with an int - this replaces the string value
|
||||||
|
await preferences.setInt(key, 42);
|
||||||
|
expect(await preferences.getInt(key), 42);
|
||||||
|
|
||||||
|
// Overwrite with a bool - this replaces the int value
|
||||||
|
await preferences.setBool(key, true);
|
||||||
|
expect(await preferences.getBool(key), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('persistence works across multiple operations', () async {
|
||||||
|
// Test that values persist through multiple set/get operations
|
||||||
|
await preferences.setString('key1', 'value1');
|
||||||
|
await preferences.setInt('key2', 100);
|
||||||
|
|
||||||
|
expect(await preferences.getString('key1'), 'value1');
|
||||||
|
expect(await preferences.getInt('key2'), 100);
|
||||||
|
|
||||||
|
// Modify one value and ensure the other remains
|
||||||
|
await preferences.setString('key1', 'newValue1');
|
||||||
|
expect(await preferences.getString('key1'), 'newValue1');
|
||||||
|
expect(await preferences.getInt('key2'), 100);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user