Skip to content

fix: method "keys" return an immutable copy of the cache keys #166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Method "keys" for listing all cache keys —
[152](https://github.com/dartoos-dev/json_cache/issues/152)

### Changed

- update linting rules —
- Mehtod "keys" returns an immutable copy of the underlying cache keys —
[165](https://github.com/dartoos-dev/json_cache/issues/152)

- Update linting rules —
[162](https://github.com/dartoos-dev/json_cache/issues/154).


## [3.0.2] - 2024-08-19

### Changed

- Bump up dependencies —
- Updated dependencies —
[154](https://github.com/dartoos-dev/json_cache/issues/154).

### Fixed

- Removed code warnings and upgraded dart SDK range and each dependency to latest resolvable version available - [148](https://github.com/dartoos-dev/json_cache/issues/148).
- Remove code warnings and upgrade the dart SDK range. In addition,
dependencies were updated to the latest resolvable version —
[148](https://github.com/dartoos-dev/json_cache/issues/148).

## [3.0.1] - 2023-08-10

### Fixed

- removed unused package 'cross_local_storage' from pubspec —
- Removed unused package 'cross_local_storage' from pubspec —
[144](https://github.com/dartoos-dev/json_cache/issues/144).

## [3.0.0] - 2023-08-10

### Removed

- support for the 'cross_local_storage' package — **BREAKING CHANGE** —
- Support for the 'cross_local_storage' package — **BREAKING CHANGE** —
[140](https://github.com/dartoos-dev/json_cache/issues/140).

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions lib/src/json_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ abstract class JsonCache {
/// Returns `true` if there is cached data at [key]; `false` otherwise.
Future<bool> contains(String key);

/// Lists all keys.
/// The cache keys.
///
/// Returns an **unmodifiable** list of cache keys without duplicates.
/// Returns an **unmodifiable** list of all cache keys without duplicates.
Future<UnmodifiableListView<String>> keys();
}
2 changes: 1 addition & 1 deletion lib/src/json_cache_fake.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ class JsonCacheFake implements JsonCache {

@override
Future<UnmodifiableListView<String>> keys() async {
return UnmodifiableListView(_memory.keys);
return UnmodifiableListView(List.unmodifiable(_memory.keys));
}
}
4 changes: 3 additions & 1 deletion lib/src/json_cache_hive.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class JsonCacheHive implements JsonCache {

@override
Future<UnmodifiableListView<String>> keys() async {
return UnmodifiableListView(_box.keys.map((k) => k as String));
return UnmodifiableListView(
_box.keys.map((k) => k as String).toList(growable: false),
);
}
}
2 changes: 1 addition & 1 deletion lib/src/json_cache_mem.dart
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class JsonCacheMem implements JsonCache {
@override
Future<UnmodifiableListView<String>> keys() {
return _mutex.protectRead(() async {
return UnmodifiableListView(_memory.keys);
return UnmodifiableListView(_memory.keys.toList(growable: false));
});
}
}
3 changes: 1 addition & 2 deletions lib/src/json_cache_safe_local_storage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,8 @@ class JsonCacheSafeLocalStorage implements JsonCache {

@override
Future<UnmodifiableListView<String>> keys() async {
final data = await _cachedData;
return UnmodifiableListView(
data.keys.map((k) => k as String),
(await _cachedData).keys.map((k) => k as String),
);
}

Expand Down
27 changes: 19 additions & 8 deletions test/json_cache_fake_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:json_cache/json_cache.dart';

void main() {
group('JsonCacheFake', () {
group('JsonCacheFake:', () {
const profKey = 'profile';
const prefKey = 'preferences';
const profData = <String, dynamic>{'id': 1, 'name': 'John Due'};
Expand Down Expand Up @@ -65,13 +65,24 @@ void main() {
expect(await fake.contains(prefKey), false);
expect(await fake.contains('a key'), false);
});
test('keys', () async {
final fake = JsonCacheFake();
// update data
await fake.refresh(profKey, profData);
await fake.refresh(prefKey, prefData);

expect(await fake.keys(), [profKey, prefKey]);
group('method "keys"', () {
late JsonCacheFake fakeCache;
setUp(() async {
fakeCache = JsonCacheFake();
// update data
await fakeCache.refresh(profKey, profData);
await fakeCache.refresh(prefKey, prefData);
});
test('should return the inserted keys', () async {
expect(await fakeCache.keys(), [profKey, prefKey]);
});
test('should keep the returned keys immutable', () async {
final keys = await fakeCache.keys();
// This should not change the 'keys' variable.
await fakeCache
.refresh('info', {'This is very important information.': true});
expect(keys, [profKey, prefKey]);
});
});
group('remove', () {
test('default ctor', () async {
Expand Down
29 changes: 20 additions & 9 deletions test/json_cache_flutter_secure_storage_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:json_cache/json_cache.dart';
import 'flutter_secure_storage_mock.dart';

void main() {
group('JsonCacheFlutterSecureStorage', () {
group('JsonCacheFlutterSecureStorage:', () {
const profKey = 'profile';
const prefKey = 'preferences';
const profData = <String, dynamic>{'id': 1, 'name': 'John Due'};
Expand Down Expand Up @@ -50,15 +50,26 @@ void main() {
await flutterSecureCache.remove(prefKey);
expect(await flutterSecureCache.contains(prefKey), false);
});
test('keys', () async {
final secStorageMock = FlutterSecureStorageMock();
final JsonCacheFlutterSecureStorage flutterSecureCache =
JsonCacheFlutterSecureStorage(secStorageMock);
// update data
await flutterSecureCache.refresh(profKey, profData);
await flutterSecureCache.refresh(prefKey, prefData);

expect(await flutterSecureCache.keys(), [profKey, prefKey]);
group('method "keys"', () {
late JsonCacheFlutterSecureStorage flutterSecureCache;
setUp(() async {
flutterSecureCache =
JsonCacheFlutterSecureStorage(FlutterSecureStorageMock());
// update data
await flutterSecureCache.refresh(profKey, profData);
await flutterSecureCache.refresh(prefKey, prefData);
});
test('should return the inserted keys', () async {
expect(await flutterSecureCache.keys(), [profKey, prefKey]);
});
test('should keep the returned keys immutable', () async {
final keys = await flutterSecureCache.keys();
// This should not change the 'keys' variable.
await flutterSecureCache
.refresh('info', {'This is very important information.': true});
expect(keys, [profKey, prefKey]);
});
});
test('remove', () async {
final secStorageMock = FlutterSecureStorageMock();
Expand Down
30 changes: 20 additions & 10 deletions test/json_cache_hive_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ void main() {
tearDown(() async {
await tearDownTestHive();
});
group('JsonCacheHive', () {
group('JsonCacheHive:', () {
const profKey = 'profile';
const prefKey = 'preferences';
const profData = <String, dynamic>{'id': 1, 'name': 'John Due'};
Expand Down Expand Up @@ -47,15 +47,25 @@ void main() {
await hiveCache.remove(prefKey);
expect(await hiveCache.contains(prefKey), false);
});

test('keys', () async {
final box = await Hive.openBox<String>('test-contains-method');
final JsonCacheHive hiveCache = JsonCacheHive(box);
// update data
await hiveCache.refresh(profKey, profData);
await hiveCache.refresh(prefKey, prefData);

expect(await hiveCache.keys(), [prefKey, profKey]);
group('method "keys"', () {
late JsonCacheHive hiveCache;
setUp(() async {
final box = await Hive.openBox<String>('test-keys-method');
hiveCache = JsonCacheHive(box);
// update data
await hiveCache.refresh(profKey, profData);
await hiveCache.refresh(prefKey, prefData);
});
test('should return the inserted keys', () async {
expect(await hiveCache.keys(), [prefKey, profKey]);
});
test('should keep the returned keys immutable', () async {
final keys = await hiveCache.keys();
// This should not change the 'keys' variable.
await hiveCache
.refresh('info', {'This is very important information.': true});
expect(keys, [prefKey, profKey]);
});
});
test('remove', () async {
final box = await Hive.openBox<String>('test-remove');
Expand Down
16 changes: 11 additions & 5 deletions test/json_cache_hollow_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:json_cache/json_cache.dart';

void main() {
group('JsonCacheHollow', () {
group('JsonCacheHollow:', () {
const profKey = 'profile';
const prefKey = 'preferences';
const profData = <String, dynamic>{'id': 1, 'name': 'John Due'};
Expand Down Expand Up @@ -36,11 +36,17 @@ void main() {
expect(await fake.contains('a key'), false);
});
test('keys', () async {
const fake = JsonCacheHollow();
await fake.refresh(profKey, profData);
await fake.refresh(prefKey, prefData);
const hollowCache = JsonCacheHollow();
await hollowCache.refresh(profKey, profData);
await hollowCache.refresh(prefKey, prefData);

final keys = await hollowCache.keys();
expect(keys, const []);

expect(await fake.keys(), const []);
// This should not change the 'keys' variable.
await hollowCache
.refresh('info', {'This is very important information.': true});
expect(keys, const []);
});
test('remove', () async {
const JsonCacheHollow hollowCache = JsonCacheHollow();
Expand Down
29 changes: 20 additions & 9 deletions test/json_cache_local_storage_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import 'package:json_cache/json_cache.dart';
import 'fake_local_storage.dart';

void main() {
group('JsonCacheLocalStorage', () {
group('JsonCacheLocalStorage:', () {
const profKey = 'profile';
const prefKey = 'preferences';
const profData = <String, Object>{'id': 1, 'name': 'John Due'};
const prefData = <String, dynamic>{
'theme': 'dark',
Expand Down Expand Up @@ -40,14 +41,24 @@ void main() {
expect(await jsonCache.contains(prefKey), false);
});

test('keys', () async {
const prefKey = 'preferences';
final JsonCacheLocalStorage jsonCache = _fakeInstance;
// update data
await jsonCache.refresh(profKey, profData);
await jsonCache.refresh(prefKey, prefData);

expect(await jsonCache.keys(), [profKey, prefKey]);
group('method "keys"', () {
late JsonCacheLocalStorage localStorageCache;
setUp(() async {
localStorageCache = JsonCacheLocalStorage(FakeLocalStorage());
// update data
await localStorageCache.refresh(profKey, profData);
await localStorageCache.refresh(prefKey, prefData);
});
test('should return the inserted keys', () async {
expect(await localStorageCache.keys(), [profKey, prefKey]);
});
test('should keep the returned keys immutable', () async {
final keys = await localStorageCache.keys();
// This should not change the 'keys' variable.
await localStorageCache
.refresh('info', {'This is very important information.': true});
expect(keys, [profKey, prefKey]);
});
});
test('remove', () async {
const prefKey = 'preferences';
Expand Down
Loading