Skip to content

Commit

Permalink
[shared_preferences] Migrate platform plugins to null-safety (flutter…
Browse files Browse the repository at this point in the history
…#3523)

Migrates shared_preferences_linux and shared_preferences_web to null-safety.
  • Loading branch information
gaetschwartz authored Feb 8, 2021
1 parent 7adfc2f commit 2b6addf
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.0.4-nullsafety

* Migrate to null-safety.

## 0.0.3+1

* Update Flutter SDK constraint.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import 'dart:async';

import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:integration_test/integration_test.dart';
import 'package:shared_preferences_linux/shared_preferences_linux.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('$SharedPreferences', () {
group('SharedPreferencesLinux', () {
const Map<String, dynamic> kTestValues = <String, dynamic>{
'flutter.String': 'hello world',
'flutter.bool': true,
Expand All @@ -23,67 +24,73 @@ void main() {
'flutter.List': <String>['baz', 'quox'],
};

SharedPreferences preferences;
SharedPreferencesLinux preferences;

setUp(() async {
preferences = await SharedPreferences.getInstance();
preferences = SharedPreferencesLinux.instance;
});

tearDown(() {
preferences.clear();
});

testWidgets('reading', (WidgetTester _) async {
expect(preferences.get('String'), isNull);
expect(preferences.get('bool'), isNull);
expect(preferences.get('int'), isNull);
expect(preferences.get('double'), isNull);
expect(preferences.get('List'), isNull);
expect(preferences.getString('String'), isNull);
expect(preferences.getBool('bool'), isNull);
expect(preferences.getInt('int'), isNull);
expect(preferences.getDouble('double'), isNull);
expect(preferences.getStringList('List'), isNull);
final all = await preferences.getAll();
expect(all['String'], isNull);
expect(all['bool'], isNull);
expect(all['int'], isNull);
expect(all['double'], isNull);
expect(all['List'], isNull);
});

testWidgets('writing', (WidgetTester _) async {
await Future.wait(<Future<bool>>[
preferences.setString('String', kTestValues2['flutter.String']),
preferences.setBool('bool', kTestValues2['flutter.bool']),
preferences.setInt('int', kTestValues2['flutter.int']),
preferences.setDouble('double', kTestValues2['flutter.double']),
preferences.setStringList('List', kTestValues2['flutter.List'])
preferences.setValue(
'String', 'String', kTestValues2['flutter.String']),
preferences.setValue('Bool', 'bool', kTestValues2['flutter.bool']),
preferences.setValue('Int', 'int', kTestValues2['flutter.int']),
preferences.setValue(
'Double', 'double', kTestValues2['flutter.double']),
preferences.setValue('StringList', 'List', kTestValues2['flutter.List'])
]);
expect(preferences.getString('String'), kTestValues2['flutter.String']);
expect(preferences.getBool('bool'), kTestValues2['flutter.bool']);
expect(preferences.getInt('int'), kTestValues2['flutter.int']);
expect(preferences.getDouble('double'), kTestValues2['flutter.double']);
expect(preferences.getStringList('List'), kTestValues2['flutter.List']);
final all = await preferences.getAll();
expect(all['String'], kTestValues2['flutter.String']);
expect(all['bool'], kTestValues2['flutter.bool']);
expect(all['int'], kTestValues2['flutter.int']);
expect(all['double'], kTestValues2['flutter.double']);
expect(all['List'], kTestValues2['flutter.List']);
});

testWidgets('removing', (WidgetTester _) async {
const String key = 'testKey';
await preferences.setString(key, kTestValues['flutter.String']);
await preferences.setBool(key, kTestValues['flutter.bool']);
await preferences.setInt(key, kTestValues['flutter.int']);
await preferences.setDouble(key, kTestValues['flutter.double']);
await preferences.setStringList(key, kTestValues['flutter.List']);

await Future.wait([
preferences.setValue('String', key, kTestValues['flutter.String']),
preferences.setValue('Bool', key, kTestValues['flutter.bool']),
preferences.setValue('Int', key, kTestValues['flutter.int']),
preferences.setValue('Double', key, kTestValues['flutter.double']),
preferences.setValue('StringList', key, kTestValues['flutter.List'])
]);
await preferences.remove(key);
expect(preferences.get('testKey'), isNull);
final all = await preferences.getAll();
expect(all['testKey'], isNull);
});

testWidgets('clearing', (WidgetTester _) async {
await preferences.setString('String', kTestValues['flutter.String']);
await preferences.setBool('bool', kTestValues['flutter.bool']);
await preferences.setInt('int', kTestValues['flutter.int']);
await preferences.setDouble('double', kTestValues['flutter.double']);
await preferences.setStringList('List', kTestValues['flutter.List']);
await Future.wait(<Future<bool>>[
preferences.setValue('String', 'String', kTestValues['flutter.String']),
preferences.setValue('Bool', 'bool', kTestValues['flutter.bool']),
preferences.setValue('Int', 'int', kTestValues['flutter.int']),
preferences.setValue('Double', 'double', kTestValues['flutter.double']),
preferences.setValue('StringList', 'List', kTestValues['flutter.List'])
]);
await preferences.clear();
expect(preferences.getString('String'), null);
expect(preferences.getBool('bool'), null);
expect(preferences.getInt('int'), null);
expect(preferences.getDouble('double'), null);
expect(preferences.getStringList('List'), null);
final all = await preferences.getAll();
expect(all['String'], null);
expect(all['bool'], null);
expect(all['int'], null);
expect(all['double'], null);
expect(all['List'], null);
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,8 @@ description: Demonstrates how to use the shared_preferences_linux plugin.
dependencies:
flutter:
sdk: flutter
shared_preferences: any
shared_preferences_linux: ^0.1.0

dependency_overrides:
shared_preferences_linux:
path: ../
# Remove this override once the endorsement is published.
shared_preferences:
path: ../../shared_preferences/

dev_dependencies:
flutter_driver:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,43 +20,48 @@ class SharedPreferencesLinux extends SharedPreferencesStorePlatform {
static SharedPreferencesLinux instance = SharedPreferencesLinux();

/// Local copy of preferences
Map<String, Object> _cachedPreferences;
Map<String, Object>? _cachedPreferences;

/// File system used to store to disk. Exposed for testing only.
@visibleForTesting
FileSystem fs = LocalFileSystem();

/// Gets the file where the preferences are stored.
Future<File> _getLocalDataFile() async {
Future<File?> _getLocalDataFile() async {
final pathProvider = PathProviderLinux();
final directory = await pathProvider.getApplicationSupportPath();
if (directory == null) return null;
return fs.file(path.join(directory, 'shared_preferences.json'));
}

/// Gets the preferences from the stored file. Once read, the preferences are
/// maintained in memory.
Future<Map<String, Object>> _readPreferences() async {
if (_cachedPreferences != null) {
return _cachedPreferences;
return _cachedPreferences!;
}

_cachedPreferences = {};
var localDataFile = await _getLocalDataFile();
if (localDataFile.existsSync()) {
Map<String, Object> preferences = {};
final File? localDataFile = await _getLocalDataFile();
if (localDataFile != null && localDataFile.existsSync()) {
String stringMap = localDataFile.readAsStringSync();
if (stringMap.isNotEmpty) {
_cachedPreferences = json.decode(stringMap) as Map<String, Object>;
preferences = json.decode(stringMap).cast<String, Object>();
}
}

return _cachedPreferences;
_cachedPreferences = preferences;
return preferences;
}

/// Writes the cached preferences to disk. Returns [true] if the operation
/// succeeded.
Future<bool> _writePreferences(Map<String, Object> preferences) async {
try {
var localDataFile = await _getLocalDataFile();
if (localDataFile == null) {
print("Unable to determine where to write preferences.");
return false;
}
if (!localDataFile.existsSync()) {
localDataFile.createSync(recursive: true);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: shared_preferences_linux
description: Linux implementation of the shared_preferences plugin
version: 0.0.3+1
version: 0.0.4-nullsafety
homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_linux

flutter:
Expand All @@ -11,17 +11,17 @@ flutter:
pluginClass: none

environment:
sdk: ">=2.1.0 <3.0.0"
sdk: ">=2.12.0-0 <3.0.0"
flutter: ">=1.12.8"

dependencies:
file: ">=5.1.0 <7.0.0"
flutter:
sdk: flutter
file: ^6.0.0-nullsafety.4
meta: ^1.0.4
path: ^1.6.4
path_provider_linux: ^0.0.1
shared_preferences_platform_interface: ^1.0.0
path: ^1.8.0-nullsafety.3
path_provider_linux: ^0.2.0-nullsafety
shared_preferences_platform_interface: ^2.0.0-nullsafety

dev_dependencies:
flutter_test:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import 'package:path/path.dart' as path;
import 'package:path_provider_linux/path_provider_linux.dart';
import 'package:shared_preferences_linux/shared_preferences_linux.dart';

MemoryFileSystem fs;

void main() {
late MemoryFileSystem fs;

setUp(() {
fs = MemoryFileSystem.test();
});
Expand All @@ -19,7 +19,7 @@ void main() {
Future<String> _getFilePath() async {
final pathProvider = PathProviderLinux();
final directory = await pathProvider.getApplicationSupportPath();
return path.join(directory, 'shared_preferences.json');
return path.join(directory!, 'shared_preferences.json');
}

_writeTestFile(String value) async {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.2.0-nullsafety

* Migrate to null-safety.

## 0.1.2+8

* Update Flutter SDK constraint.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'package:shared_preferences_platform_interface/shared_preferences_platfor
/// This class implements the `package:shared_preferences` functionality for the web.
class SharedPreferencesPlugin extends SharedPreferencesStorePlatform {
/// Registers this class as the default instance of [SharedPreferencesStorePlatform].
static void registerWith(Registrar registrar) {
static void registerWith(Registrar? registrar) {
SharedPreferencesStorePlatform.instance = SharedPreferencesPlugin();
}

Expand All @@ -31,9 +31,9 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform {

@override
Future<Map<String, Object>> getAll() async {
final Map<String, Object> allData = <String, Object>{};
final Map<String, Object> allData = {};
for (String key in _storedFlutterKeys) {
allData[key] = _decodeValue(html.window.localStorage[key]);
allData[key] = _decodeValue(html.window.localStorage[key]!);
}
return allData;
}
Expand All @@ -46,7 +46,7 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform {
}

@override
Future<bool> setValue(String valueType, String key, Object value) async {
Future<bool> setValue(String valueType, String key, Object? value) async {
_checkPrefix(key);
html.window.localStorage[key] = _encodeValue(value);
return true;
Expand All @@ -62,17 +62,12 @@ class SharedPreferencesPlugin extends SharedPreferencesStorePlatform {
}
}

List<String> get _storedFlutterKeys {
final List<String> keys = <String>[];
for (String key in html.window.localStorage.keys) {
if (key.startsWith('flutter.')) {
keys.add(key);
}
}
return keys;
Iterable<String> get _storedFlutterKeys {
return html.window.localStorage.keys
.where((key) => key.startsWith('flutter.'));
}

String _encodeValue(Object value) {
String _encodeValue(Object? value) {
return json.encode(value);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/shared_prefere
# 0.1.y+z is compatible with 1.0.0, if you land a breaking change bump
# the version to 2.0.0.
# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0
version: 0.1.2+8
version: 0.2.0-nullsafety

flutter:
plugin:
Expand All @@ -14,7 +14,7 @@ flutter:
fileName: shared_preferences_web.dart

dependencies:
shared_preferences_platform_interface: ^1.0.0
shared_preferences_platform_interface: ^2.0.0-nullsafety
flutter:
sdk: flutter
flutter_web_plugins:
Expand All @@ -27,5 +27,5 @@ dev_dependencies:
pedantic: ^1.8.0

environment:
sdk: ">=2.1.0 <3.0.0"
sdk: ">=2.12.0-0 <3.0.0"
flutter: ">=1.12.13+hotfix.4"
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

@TestOn('chrome') // Uses web-only Flutter SDK

@TestOn('chrome')
import 'dart:convert' show json;
import 'dart:html' as html;

import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences_platform_interface/method_channel_shared_preferences.dart';
import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart';
import 'package:shared_preferences_web/shared_preferences_web.dart';

Expand All @@ -26,6 +26,8 @@ void main() {
});

test('registers itself', () {
SharedPreferencesStorePlatform.instance =
MethodChannelSharedPreferencesStore();
expect(SharedPreferencesStorePlatform.instance,
isNot(isA<SharedPreferencesPlugin>()));
SharedPreferencesPlugin.registerWith(null);
Expand Down

0 comments on commit 2b6addf

Please sign in to comment.