Medialibrary stub
Description
This is a work in progress for the medialibrary stub.
VLC-Android can run with the stub, even though there are some things to fix still
Motivation and Context
The goal is the be able to run automated tests on a device / emulated environment that does not have medias.
For that the medialibrary needed to be abstracted to be, at request, replaced by a media datasource with fake medias, and not break the app.
How Has This Been Tested?
This has been tested by running vlc-android with the stub.
Again, this is not completely stable yet. I wanted to publish it, so that it could begin being reviewed, and so that @shivanshs9 could start working with it.
How does it work ?
This abstracts the medialibrary, and all media classes that relied on the native medialibrary.
To choose at run time which implementation to use, there is a ServiceLocator that calls the appropriate implementations' constructor.
Hence instead of calling Folder(...) now you should use ServiceLocator.getAFolder(...) which will return the correct instance.
To set the service locator to return the stub instead of the native medialibrary classes, use:
ServiceLocator.setLocatorMode(ServiceLocator.LocatorMode.TESTS)
-
Bug fix (non-breaking change which fixes an issue) -
New feature (non-breaking change which adds functionality) -
Enhancement (non-breaking change which cleans up / improves existing functionality) -
Breaking change (fix or feature that would cause existing functionality to change) -> Should not break anything
Still to be done
-
Rename ServiceLocator to MLlocator -
Add fake medias -
Fix vlc-android were it will crash without actual media -
Rename all Aclasses to AbstractClasses
Merge request reports
Activity
I've merged your implementation with my tests. Although, I had some doubts regarding your service locator pattern implementation, since I am not sure hardcoding all constructors of all the components in one class is a way to go. It'll just bloat one thing with details of every components killing the concept of decoupling. Can we have something like Abstract Factory Manager design pattern? Would achieve the same result by simply registering a different factory for test. Or maybe the service locator pattern could be generalised to differentiate between components instantiation depending on type of object needed. Once the type is distinguished, we just need to call the correct type of constructor to get the needed object.
Examples of the Abstract Factory Manager pattern I'm talking about:
Then we just need to register a different factory.
I think that what you propose is needlessly complicated for our context. Would we have had more than two concurrent implementations of the medialibrary abstraction, I would agree with you, but in our case, I worry that it would harm readability.
As for the bloated class, I agree that it is much, but it is only straightforward logicless boilerplate code, and I think that it is better to have that boilerplate all in one place.
Okay, then I'll be working with your current stubs. I've updated my tests and changed some bit of stubs to make the test work. I've pushed the latest code in merged_stubs@shivanshs9/vlc-android branch. We just gotta decide the repo to use so that we both work on the latest code.
@Skantes Oh, and sorry, but I had to cherry-pick your commits to merge them because rebase just wasn't working. It was rewinding my HEAD and I was losing either yours or my commits.
Edited by Shivansh Saini@Skantes never mind the previous comment. I've rebased properly this time and all your commits are preserved in the merged@shivanshs9/vlc-android. This time, I used Android Studio for rebase and checked out your branch before rebasing all the commits from my branch. Hopefully, we won't get stuck in the Rebase Hell again
I was thinking to change the behavior of init method in StubDataSource to allow setting the scanned mediawrapper dynamically from the tests. I don't suppose it's wise to code my tests to the files coded in StubDataSource and then have them break when that will change. So, I was thinking to go by a declarative approach in each test to setup files and stuff to scan everytime.
Checkout this commit - shivanshs9/vlc-android@4440476b for how it could be handled. It wouldn't bloat the tests much. I needed to change the stubs data to test pagination stuff too.
262 269 263 270 // Test 271 testImplementation project(":medialibrary") 264 272 androidTestImplementation "androidx.test.espresso:espresso-contrib:$rootProject.espressoVersion" 265 273 androidTestImplementation "androidx.test.espresso:espresso-core:$rootProject.espressoVersion" 266 274 testImplementation "junit:junit:$rootProject.ext.junitVersion" 267 275 androidTestImplementation "androidx.room:room-testing:$rootProject.ext.roomVersion" 268 276 testImplementation "androidx.arch.core:core-testing:$rootProject.ext.archVersion" 269 277 androidTestImplementation "androidx.arch.core:core-testing:$rootProject.ext.archVersion" 270 androidTestImplementation "androidx.test:runner:$rootProject.ext.supportTest" 278 androidTestImplementation "androidx.test.ext:junit:$rootProject.ext.supportTest" 271 279 androidTestUtil "androidx.test:orchestrator:$rootProject.ext.supportTest" 272 280 testImplementation "org.mockito:mockito-core:$rootProject.ext.mockito" 273 281 testImplementation "org.powermock:powermock-api-mockito2:$rootProject.ext.powerMock" 274 282 testImplementation "org.powermock:powermock-module-junit4:$rootProject.ext.powerMock" 283 androidTestImplementation 'androidx.test:rules:1.2.0-alpha05' changed this line in version 3 of the diff
87 88 private native AbstractAlbum[] nativeGetAlbums(AbstractMedialibrary ml, long mId, int sort, boolean desc); 89 private native AbstractArtist[] nativeGetArtists(AbstractMedialibrary ml, long mId, int sort, boolean desc); 90 private native AbstractMediaWrapper[] nativeGetTracks(AbstractMedialibrary ml, long mId, int sort, boolean desc); 91 92 private native AbstractAlbum[] nativeGetPagedAlbums(AbstractMedialibrary ml, long mId, int sort, boolean desc, int nbItems, int offset); 93 private native AbstractArtist[] nativeGetPagedArtists(AbstractMedialibrary ml, long mId, int sort, boolean desc, int nbItems, int offset); 94 private native AbstractMediaWrapper[] nativeGetPagedTracks(AbstractMedialibrary ml, long mId, int sort, boolean desc, int nbItems, int offset); 95 private native int nativeGetTracksCount(AbstractMedialibrary ml, long id); 96 private native int nativeGetAlbumsCount(AbstractMedialibrary ml, long mId); 97 private native int nativeGetArtistsCount(AbstractMedialibrary ml, long mId); 98 private native AbstractAlbum[] nativeSearchAlbums(AbstractMedialibrary ml, long mId, String query, int sort, boolean desc, int nbItems, int offset); 99 private native AbstractMediaWrapper[] nativeSearch(AbstractMedialibrary ml, long mId, String query, int sort, boolean desc, int nbItems, int offset); 100 private native int nativeGetSearchCount(AbstractMedialibrary ml, long mId, String query); 101 private native int nativeGetSearchAlbumCount(AbstractMedialibrary ml, long mId, String query); 102 added 45 commits
-
b05e31f6...27f02f7e - 34 commits from branch
videolan:master
- 8ee5cd04 - Update JUnit
- 31f61415 - Medialibrary: move MediaWrapper to AMediaWrapper
- ead2e2f1 - Medialibrary: move Artist to AArtist
- fa5fec85 - Medialibrary: move Genre to AGenre
- d2519832 - Medialibrary: move Album to AAlbum
- 418bbc70 - Medialibrary: move Folder to AFolder
- a02ea8a5 - Medialibrary: move Playlist to APlaylist
- f24fa2a5 - Medialibrary: move Medialibrary to AMedialibrary
- 18f2fe8c - Medialibrary: Add stub
- 6711a3e4 - Medialibrary: add ML to ServiceLocator name
- 58ff3e09 - Medialibrary: rename AClasses into AbstractClasses
Toggle commit list-
b05e31f6...27f02f7e - 34 commits from branch