-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Convert Shared Preferences Android to Pigeon #7015
Convert Shared Preferences Android to Pigeon #7015
Conversation
…h-sharedprefs-android-to-pigeon
@tarrinneal Could you please guide me with how can I pass through the CI/CD Pipeline, the tests were running and the example is also running fine as expected. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution!
packages/shared_preferences/shared_preferences_android/CHANGELOG.md
Outdated
Show resolved
Hide resolved
...ndroid/android/src/main/java/io/flutter/plugins/sharedpreferences/MethodCallHandlerImpl.java
Outdated
Show resolved
Hide resolved
...roid/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java
Show resolved
Hide resolved
packages/shared_preferences/shared_preferences_android/pigeons/messages.dart
Outdated
Show resolved
Hide resolved
...roid/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java
Outdated
Show resolved
Hide resolved
Seems like you got it, nice work. I'll go ahead and review after you fix Stuarts requests. Thank you for contributing! |
…on upgrade to 3.0.0
I have made the changes but I am facing issues with File Formatting, however I'm trying to fix it. Once I fix it I will raise a review check. Sorry for the delay |
Hey, there I successfully fixed the error regarding Code Formatting. |
packages/shared_preferences/shared_preferences_android/CHANGELOG.md
Outdated
Show resolved
Hide resolved
…h-sharedprefs-android-to-pigeon
Hey, there I reverted the unwanted changes caused by linting. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed all reviews successfully :)
Hey, is there some issue with the PR? Can I help with it? |
|
||
/** Helper class to save data to `android.content.SharedPreferences` */ | ||
|
||
// Rename class and file to match it's purpose, preferably SharedPreferencesHelper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you would still like to make this change, I think another pr that does only this would be a good idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I change the name perhaps? I was asked to make minimal changes, so I didn't change the file name as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think both in a follow up pr would be ideal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah sure, do I have to do it after this PR is merged? I am sorry for the lame question😔, this is my first time contributing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can put the pr up whenever, I think it would be easier to wait till this one is landed though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay sure! Thanks a lot again(🙂).
What issue are you referring to? |
I thought it wasn't getting merged perhaps I am missing something at my end. |
PRs don't get merged before they are approved by reviewers; please read https://github.com/flutter/flutter/wiki/Tree-hygiene#getting-a-code-review (and 11 hours since your last update is not a reasonable window of time before pinging reviewers; re-review can take a while depending on people's schedules). |
I am really sorry, I will make sure not to tag any contributor/maintainer. |
Hey there, any updates regarding this PR? 😊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently I hadn't published my review comments; they were still in Pending mode.
@HostApi(dartHostTestHandler: 'TestSharedPreferencesApi') | ||
abstract class SharedPreferencesApi { | ||
@TaskQueue(type: TaskQueueType.serialBackgroundThread) | ||
bool remove(String key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add documentation comments on each method explaining what they do.
@@ -25,3 +25,4 @@ dependencies: | |||
dev_dependencies: | |||
flutter_test: | |||
sdk: flutter | |||
pigeon: ^7.0.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be updated to ^8.0.0
.
import '../test/messages_test.g.dart'; | ||
|
||
// Mock Implementation of the SharedPreferencesApi | ||
class _MockAPI extends TestSharedPreferencesApi { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a fake, not a mock, so should be named accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will rename it. 😊
|
||
/** Helper class to save data to `android.content.SharedPreferences` */ | ||
|
||
// Rename class and file to match it's purpose, preferably SharedPreferencesHelper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#avoid-checking-in-comments-that-ask-questions for TODO comment style.
.remove(key) | ||
.putString(key, LIST_IDENTIFIER + encodeList(listValue)) | ||
.commit(); | ||
} catch (RuntimeException e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look like you addressed my question from before: why are you throwing an exception for the sole purpose of rethrowing it? This doesn't accomplish anything unless I'm missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for that, I have now fixed it. Now I have mitigated the functions to handle IOException
and the wrapper functions then convert it to RuntimeException.
api.setDouble("Pie", 3.14); | ||
api.setStringList("Names", Arrays.asList("Flutter", "Dart")); | ||
api.setBool("NewToFlutter", false); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused by the changes in this file; you created a mock, and then you wrote unit tests of the mock. There is absolutely no production code being tested in these tests.
The point of unit tests is to test the actual code. If you need to mock out the underlying system API that's one thing (although it's not clear to me that that's necessary here), but you can't mock out everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote these tests so that the user can easily understand what all functions are available and what all values can be passed. I am using Fake Tests because we can't access the SharedPreferencesPlugin
in Unit Tests. If I am wrong about it, please let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote these tests so that the user can easily understand what all functions are available and what all values can be passed.
The purpose of unit tests is to test code; documentation belongs in comments.
I am using Fake Tests because we can't access the
SharedPreferencesPlugin
in Unit Tests.
Why wouldn't unit tests be able to access code under test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because under SharedPreferencesPlugin.java
we are using android.content.SharedPreferences
and other libraries which can only execute when we test on an Emulator/device.
I took inspiration for tests from here.
Let me know if I'm wrong here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because under
SharedPreferencesPlugin.java
we are usingandroid.content.SharedPreferences
and other libraries which can only execute when we test on an Emulator/device.
Internal implementation details that aren't available in unit tests can be mocked out, per my comment above.
I took inspiration for tests from here.
Let me know if I'm wrong here.
That is testing a small utility, not the plugin itself, so isn't going to be very useful as an example. But even then, that's testing actual code, not testing test mocks, so is serving a useful test purpose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there, I went through the examples and I was able to create some tests using MockedSharedPreferencesPlugin
.
- I tried, mocking
android.content.SharedPreferences
: I tried this method but it results in a chain of mapping methods similar to the approach I have followed. - I don't think we will be able to test the production code like the code under
MethodCallHandlerImpl
because it requires several mocked objects with chained methodsMockito.when()
to map methods.
Here, is the updated test. I am really unsure about how to write tests for this because there are not many references of tests with packages using Pigeon
.
plugin.setup(registrar.messenger(), registrar.context()); | ||
} | ||
|
||
@SuppressLint("LongLogTag") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you using a tag so long that it violates linter rules?
return preferences; | ||
} | ||
|
||
// Call the function according to the type of value provided | ||
Future<bool?> _handleSetValue( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the future type nullable?
'set$valueType', | ||
<String, dynamic>{'key': key, 'value': value}, | ||
))!; | ||
return await _handleSetValue(valueType, key, value) ?? false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of extracting the helper here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Earlier setDataType
was used, as at the Android
end we used to get its name from callMethod
. However, it makes more sense to filter that at the Dart End. Either way, this function has to be created at either Dart or Android end (which maps setDataType
string to a function according to the dataType).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not asking why the code that's currently in the helper exists, I'm asking why it's in a helper that's only called from one place, where that place ends up being just a single line calling that helper, rather than that code being here. I don't see what value the indirection is providing.
List<String> data = (List<String>) stream.readObject(); | ||
if (stream != null) { | ||
stream.close(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you remove the cleanup steps from finally
blocks? That regresses behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sorry for removing the cleanup process. I have updated the finally
block in all required scenarios.
We've just completed the migration of the plugin code to the flutter/packages repository, as described in https://flutter.dev/go/flutter-plugins-repo-migration, and this repository is now being archived. Unfortunately that means that all in-progress PRs here must be moved to flutter/packages. Please see our instructions for an explanation of how to move your PR, and if you have any issues moving your PR please don't hesitate to reach out in the #hackers-ecosystem channel in Discord. Our apologies that your PR was caught in this one-time transition. We're aware that it's disruptive in the short term, and appreciate your help in getting us to a better long-term state! |
Changes
Converted the Android Implementation of shared_preferences to Pigeon. The files
messages.g.dart
andMessages.java
are autogenerated by Pigeon according to the template provided inpigeons/messages.dart
.path_provider
package as it is already converted to pigeon.Issue
Part of flutter/flutter#117914
Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style.///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.