Skip to content

Commit

Permalink
[shared_preferences] Adds new clearWithParameters and getAllWithParam…
Browse files Browse the repository at this point in the history
…eters methods to all platforms. (#4262)

Adds new `clearWithParameters` and `getAllWithParameters` methods.

part of flutter/flutter#128948

precursor to #3794

awaiting #4261

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [relevant style guides] and ran the
auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages
repo does use `dart format`.)
- [x] I signed the [CLA].
- [x] The title of the PR starts with the name of the package surrounded
by square brackets, e.g. `[shared_preferences]`
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated `pubspec.yaml` with an appropriate new version according
to the [pub versioning philosophy], or this PR is [exempt from version
changes].
- [x] I updated `CHANGELOG.md` to add a description of the change,
[following repository CHANGELOG style].
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/packages/blob/main/CONTRIBUTING.md
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[relevant style guides]:
https://github.com/flutter/packages/blob/main/CONTRIBUTING.md#style
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/wiki/Chat
[pub versioning philosophy]: https://dart.dev/tools/pub/versioning
[exempt from version changes]:
https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#version-and-changelog-updates
[following repository CHANGELOG style]:
https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changelog-style
[test-exempt]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
  • Loading branch information
tarrinneal committed Jun 29, 2023
1 parent d4752c4 commit d615371
Show file tree
Hide file tree
Showing 40 changed files with 2,428 additions and 775 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 2.2.0

* Adds `clearWithParameters` and `getAllWithParameters` methods.
* Updates minimum supported SDK version to Flutter 3.3/Dart 2.18.

## 2.1.4
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v9.2.4), do not edit directly.
// Autogenerated from Pigeon (v9.2.5), do not edit directly.
// See also: https://pub.dev/packages/pigeon

package io.flutter.plugins.sharedpreferences;
Expand Down Expand Up @@ -75,10 +75,10 @@ public interface SharedPreferencesApi {
Boolean setStringList(@NonNull String key, @NonNull List<String> value);
/** Removes all properties from shared preferences data set with matching prefix. */
@NonNull
Boolean clearWithPrefix(@NonNull String prefix);
Boolean clear(@NonNull String prefix, @Nullable List<String> allowList);
/** Gets all properties from shared preferences data set with matching prefix. */
@NonNull
Map<String, Object> getAllWithPrefix(@NonNull String prefix);
Map<String, Object> getAll(@NonNull String prefix, @Nullable List<String> allowList);

/** The codec used by SharedPreferencesApi. */
static @NonNull MessageCodec<Object> getCodec() {
Expand Down Expand Up @@ -263,7 +263,7 @@ static void setup(
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger,
"dev.flutter.pigeon.SharedPreferencesApi.clearWithPrefix",
"dev.flutter.pigeon.SharedPreferencesApi.clear",
getCodec(),
taskQueue);
if (api != null) {
Expand All @@ -272,8 +272,9 @@ static void setup(
ArrayList<Object> wrapped = new ArrayList<Object>();
ArrayList<Object> args = (ArrayList<Object>) message;
String prefixArg = (String) args.get(0);
List<String> allowListArg = (List<String>) args.get(1);
try {
Boolean output = api.clearWithPrefix(prefixArg);
Boolean output = api.clear(prefixArg, allowListArg);
wrapped.add(0, output);
} catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
Expand All @@ -290,7 +291,7 @@ static void setup(
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger,
"dev.flutter.pigeon.SharedPreferencesApi.getAllWithPrefix",
"dev.flutter.pigeon.SharedPreferencesApi.getAll",
getCodec(),
taskQueue);
if (api != null) {
Expand All @@ -299,8 +300,9 @@ static void setup(
ArrayList<Object> wrapped = new ArrayList<Object>();
ArrayList<Object> args = (ArrayList<Object>) message;
String prefixArg = (String) args.get(0);
List<String> allowListArg = (List<String>) args.get(1);
try {
Map<String, Object> output = api.getAllWithPrefix(prefixArg);
Map<String, Object> output = api.getAll(prefixArg, allowListArg);
wrapped.add(0, output);
} catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import android.util.Base64;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
Expand All @@ -21,6 +22,7 @@
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -111,18 +113,20 @@ public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding bin
}

@Override
public @NonNull Map<String, Object> getAllWithPrefix(@NonNull String prefix)
throws RuntimeException {
return getAllPrefs(prefix);
public @NonNull Map<String, Object> getAll(
@NonNull String prefix, @Nullable List<String> allowList) throws RuntimeException {
final Set<String> allowSet = allowList == null ? null : new HashSet<>(allowList);
return getAllPrefs(prefix, allowSet);
}

@Override
public @NonNull Boolean clearWithPrefix(@NonNull String prefix) throws RuntimeException {
public @NonNull Boolean clear(@NonNull String prefix, @Nullable List<String> allowList)
throws RuntimeException {
SharedPreferences.Editor clearEditor = preferences.edit();
Map<String, ?> allPrefs = preferences.getAll();
ArrayList<String> filteredPrefs = new ArrayList<>();
for (String key : allPrefs.keySet()) {
if (key.startsWith(prefix)) {
if (key.startsWith(prefix) && (allowList == null || allowList.contains(key))) {
filteredPrefs.add(key);
}
}
Expand All @@ -133,12 +137,14 @@ public void onDetachedFromEngine(@NonNull FlutterPlugin.FlutterPluginBinding bin
}

// Gets all shared preferences, filtered to only those set with the given prefix.
// Optionally filtered also to only those items in the optional [allowList].
@SuppressWarnings("unchecked")
private @NonNull Map<String, Object> getAllPrefs(@NonNull String prefix) throws RuntimeException {
private @NonNull Map<String, Object> getAllPrefs(
@NonNull String prefix, @Nullable Set<String> allowList) throws RuntimeException {
Map<String, ?> allPrefs = preferences.getAll();
Map<String, Object> filteredPrefs = new HashMap<>();
for (String key : allPrefs.keySet()) {
if (key.startsWith(prefix)) {
if (key.startsWith(prefix) && (allowList == null || allowList.contains(key))) {
filteredPrefs.put(key, transformPref(key, allPrefs.get(key)));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ public void before() {
}

@Test
public void getAllWithPrefix() {
assertEquals(plugin.getAllWithPrefix("").size(), 0);
public void getAll() {
assertEquals(plugin.getAll("", null).size(), 0);

addData();

Map<String, Object> flutterData = plugin.getAllWithPrefix("flutter.");
Map<String, Object> flutterData = plugin.getAll("flutter.", null);

assertEquals(flutterData.size(), 5);
assertEquals(flutterData.get("flutter.Language"), "Java");
Expand All @@ -81,17 +81,43 @@ public void getAllWithPrefix() {
assertEquals(flutterData.get("flutter.Names"), Arrays.asList("Flutter", "Dart"));
assertEquals(flutterData.get("flutter.NewToFlutter"), false);

Map<String, Object> allData = plugin.getAllWithPrefix("");
Map<String, Object> allData = plugin.getAll("", null);

assertEquals(allData, data);
}

@Test
public void allowList() {
assertEquals(plugin.getAll("", null).size(), 0);

addData();

final List<String> allowList = Arrays.asList("flutter.Language");

Map<String, Object> allData = plugin.getAll("flutter.", allowList);

assertEquals(allData.size(), 1);
assertEquals(allData.get("flutter.Language"), "Java");
assertEquals(allData.get("flutter.Counter"), null);

allData = plugin.getAll("", allowList);

assertEquals(allData.size(), 1);
assertEquals(allData.get("flutter.Language"), "Java");
assertEquals(allData.get("flutter.Counter"), null);

allData = plugin.getAll("prefix.", allowList);

assertEquals(allData.size(), 0);
assertEquals(allData.get("flutter.Language"), null);
}

@Test
public void setString() {
final String key = "language";
final String value = "Java";
plugin.setString(key, value);
Map<String, Object> flutterData = plugin.getAllWithPrefix("");
Map<String, Object> flutterData = plugin.getAll("", null);
assertEquals(flutterData.get(key), value);
}

Expand All @@ -100,7 +126,7 @@ public void setInt() {
final String key = "Counter";
final Long value = 0L;
plugin.setInt(key, value);
Map<String, Object> flutterData = plugin.getAllWithPrefix("");
Map<String, Object> flutterData = plugin.getAll("", null);
assertEquals(flutterData.get(key), value);
}

Expand All @@ -109,7 +135,7 @@ public void setDouble() {
final String key = "Pie";
final double value = 3.14;
plugin.setDouble(key, value);
Map<String, Object> flutterData = plugin.getAllWithPrefix("");
Map<String, Object> flutterData = plugin.getAll("", null);
assertEquals(flutterData.get(key), value);
}

Expand All @@ -118,7 +144,7 @@ public void setStringList() {
final String key = "Names";
final List<String> value = Arrays.asList("Flutter", "Dart");
plugin.setStringList(key, value);
Map<String, Object> flutterData = plugin.getAllWithPrefix("");
Map<String, Object> flutterData = plugin.getAll("", null);
assertEquals(flutterData.get(key), value);
}

Expand All @@ -127,40 +153,51 @@ public void setBool() {
final String key = "NewToFlutter";
final boolean value = false;
plugin.setBool(key, value);
Map<String, Object> flutterData = plugin.getAllWithPrefix("");
Map<String, Object> flutterData = plugin.getAll("", null);
assertEquals(flutterData.get(key), value);
}

@Test
public void clearWithPrefix() {
public void clearWithNoAllowList() {
addData();

assertEquals(plugin.getAll("", null).size(), 15);

plugin.clear("flutter.", null);

assertEquals(plugin.getAll("", null).size(), 10);
}

@Test
public void clearWithAllowList() {
addData();

assertEquals(plugin.getAllWithPrefix("").size(), 15);
assertEquals(plugin.getAll("", null).size(), 15);

plugin.clearWithPrefix("flutter.");
plugin.clear("flutter.", Arrays.asList("flutter.Language"));

assertEquals(plugin.getAllWithPrefix("").size(), 10);
assertEquals(plugin.getAll("", null).size(), 14);
}

@Test
public void clearAll() {
addData();

assertEquals(plugin.getAllWithPrefix("").size(), 15);
assertEquals(plugin.getAll("", null).size(), 15);

plugin.clearWithPrefix("");
plugin.clear("", null);

assertEquals(plugin.getAllWithPrefix("").size(), 0);
assertEquals(plugin.getAll("", null).size(), 0);
}

@Test
public void testRemove() {
final String key = "NewToFlutter";
final boolean value = true;
plugin.setBool(key, value);
assert (plugin.getAllWithPrefix("").containsKey(key));
assert (plugin.getAll("", null).containsKey(key));
plugin.remove(key);
assertFalse(plugin.getAllWithPrefix("").containsKey(key));
assertFalse(plugin.getAll("", null).containsKey(key));
}

private void addData() {
Expand Down
Loading

0 comments on commit d615371

Please sign in to comment.