mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
refactor(AsyncStorage): move android files from react-native-github
Summary: ## Changelog: [Android] [Removed] - Removed AsyncStorage module Reviewed By: lunaleaps Differential Revision: D40175995 fbshipit-source-id: b583579b8c2fa6c502f265ffe464b81672bd7da5
This commit is contained in:
committed by
Facebook GitHub Bot
parent
83e2126b57
commit
5738fe6426
@@ -37,7 +37,6 @@ rn_robolectric_test(
|
||||
react_native_target("java/com/facebook/react/modules/dialog:dialog"),
|
||||
react_native_target("java/com/facebook/react/modules/network:network"),
|
||||
react_native_target("java/com/facebook/react/modules/share:share"),
|
||||
react_native_target("java/com/facebook/react/modules/storage:storage"),
|
||||
react_native_target("java/com/facebook/react/modules/systeminfo:systeminfo"),
|
||||
react_native_target("java/com/facebook/react/touch:touch"),
|
||||
react_native_target("java/com/facebook/react/uimanager:uimanager"),
|
||||
|
||||
-345
@@ -1,345 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
package com.facebook.react.modules.storage;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.JavaOnlyArray;
|
||||
import com.facebook.react.bridge.JavaOnlyMap;
|
||||
import com.facebook.react.bridge.ReactTestHelper;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.mockito.verification.VerificationMode;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.rule.PowerMockRule;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.android.util.concurrent.RoboExecutorService;
|
||||
|
||||
/** Tests for {@link com.facebook.react.modules.storage.AsyncStorageModule}. */
|
||||
@PrepareForTest({Arguments.class})
|
||||
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "androidx.*", "android.*", "org.json.*"})
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AsyncStorageModuleTest {
|
||||
|
||||
private AsyncStorageModule mStorage;
|
||||
private JavaOnlyArray mEmptyArray;
|
||||
|
||||
@Rule public PowerMockRule rule = new PowerMockRule();
|
||||
|
||||
@Before
|
||||
public void prepareModules() {
|
||||
PowerMockito.mockStatic(Arguments.class);
|
||||
Mockito.when(Arguments.createArray())
|
||||
.thenAnswer(
|
||||
new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return new JavaOnlyArray();
|
||||
}
|
||||
});
|
||||
|
||||
Mockito.when(Arguments.createMap())
|
||||
.thenAnswer(
|
||||
new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
return new JavaOnlyMap();
|
||||
}
|
||||
});
|
||||
|
||||
// don't use Robolectric before initializing mocks
|
||||
mStorage =
|
||||
new AsyncStorageModule(
|
||||
ReactTestHelper.createCatalystContextForTest(), new RoboExecutorService());
|
||||
mEmptyArray = new JavaOnlyArray();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
RuntimeEnvironment.application.deleteDatabase(ReactDatabaseSupplier.DATABASE_NAME);
|
||||
ReactDatabaseSupplier.deleteInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiSetMultiGet() {
|
||||
final String key1 = "foo1";
|
||||
final String key2 = "foo2";
|
||||
final String fakeKey = "fakeKey";
|
||||
final String value1 = "bar1";
|
||||
final String value2 = "bar2";
|
||||
JavaOnlyArray keyValues = new JavaOnlyArray();
|
||||
keyValues.pushArray(getArray(key1, value1));
|
||||
keyValues.pushArray(getArray(key2, value2));
|
||||
|
||||
Callback setCallback = mock(Callback.class);
|
||||
mStorage.multiSet(keyValues, setCallback);
|
||||
verify(setCallback, Mockito.times(1)).invoke();
|
||||
|
||||
JavaOnlyArray keys = new JavaOnlyArray();
|
||||
keys.pushString(key1);
|
||||
keys.pushString(key2);
|
||||
|
||||
Callback getCallback = mock(Callback.class);
|
||||
mStorage.multiGet(keys, getCallback);
|
||||
verify(getCallback, Mockito.times(1)).invoke(null, keyValues);
|
||||
|
||||
keys.pushString(fakeKey);
|
||||
JavaOnlyArray row3 = new JavaOnlyArray();
|
||||
row3.pushString(fakeKey);
|
||||
row3.pushString(null);
|
||||
keyValues.pushArray(row3);
|
||||
|
||||
Callback getCallback2 = mock(Callback.class);
|
||||
mStorage.multiGet(keys, getCallback2);
|
||||
verify(getCallback2, Mockito.times(1)).invoke(null, keyValues);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiRemove() {
|
||||
final String key1 = "foo1";
|
||||
final String key2 = "foo2";
|
||||
final String value1 = "bar1";
|
||||
final String value2 = "bar2";
|
||||
|
||||
JavaOnlyArray keyValues = new JavaOnlyArray();
|
||||
keyValues.pushArray(getArray(key1, value1));
|
||||
keyValues.pushArray(getArray(key2, value2));
|
||||
mStorage.multiSet(keyValues, mock(Callback.class));
|
||||
|
||||
JavaOnlyArray keys = new JavaOnlyArray();
|
||||
keys.pushString(key1);
|
||||
keys.pushString(key2);
|
||||
|
||||
Callback getCallback = mock(Callback.class);
|
||||
mStorage.multiRemove(keys, getCallback);
|
||||
verify(getCallback, Mockito.times(1)).invoke();
|
||||
|
||||
Callback getAllCallback = mock(Callback.class);
|
||||
mStorage.getAllKeys(getAllCallback);
|
||||
verify(getAllCallback, Mockito.times(1)).invoke(null, mEmptyArray);
|
||||
|
||||
mStorage.multiSet(keyValues, mock(Callback.class));
|
||||
|
||||
keys.pushString("fakeKey");
|
||||
Callback getCallback2 = mock(Callback.class);
|
||||
mStorage.multiRemove(keys, getCallback2);
|
||||
verify(getCallback2, Mockito.times(1)).invoke();
|
||||
|
||||
Callback getAllCallback2 = mock(Callback.class);
|
||||
mStorage.getAllKeys(getAllCallback2);
|
||||
verify(getAllCallback2, Mockito.times(1)).invoke(null, mEmptyArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiMerge() throws Exception {
|
||||
final String mergeKey = "mergeTest";
|
||||
|
||||
JSONObject value = new JSONObject();
|
||||
value.put("foo1", "bar1");
|
||||
value.put("foo2", createJSONArray("val1", "val2", 3));
|
||||
value.put("foo3", 1001);
|
||||
value.put("foo4", createJSONObject("key1", "randomValueThatWillNeverBeUsed"));
|
||||
|
||||
mStorage.multiSet(JavaOnlyArray.of(getArray(mergeKey, value.toString())), mock(Callback.class));
|
||||
{
|
||||
Callback callback = mock(Callback.class);
|
||||
mStorage.multiGet(getArray(mergeKey), callback);
|
||||
verify(callback, Mockito.times(1))
|
||||
.invoke(null, JavaOnlyArray.of(getArray(mergeKey, value.toString())));
|
||||
}
|
||||
|
||||
value.put("foo1", 1001);
|
||||
value.put("foo2", createJSONObject("key1", "val1"));
|
||||
value.put("foo3", "bar1");
|
||||
value.put("foo4", createJSONArray("val1", "val2", 3));
|
||||
|
||||
JSONObject newValue = new JSONObject();
|
||||
newValue.put("foo2", createJSONObject("key2", "val2"));
|
||||
|
||||
JSONObject newValue2 = new JSONObject();
|
||||
newValue2.put("foo2", createJSONObject("key1", "val3"));
|
||||
|
||||
mStorage.multiMerge(
|
||||
JavaOnlyArray.of(
|
||||
JavaOnlyArray.of(mergeKey, value.toString()),
|
||||
JavaOnlyArray.of(mergeKey, newValue.toString()),
|
||||
JavaOnlyArray.of(mergeKey, newValue2.toString())),
|
||||
mock(Callback.class));
|
||||
|
||||
value.put("foo2", createJSONObject("key1", "val3", "key2", "val2"));
|
||||
Callback callback = mock(Callback.class);
|
||||
mStorage.multiGet(getArray(mergeKey), callback);
|
||||
verify(callback, Mockito.times(1))
|
||||
.invoke(null, JavaOnlyArray.of(getArray(mergeKey, value.toString())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllKeys() {
|
||||
final String[] keys = {"foo", "foo2"};
|
||||
final String[] values = {"bar", "bar2"};
|
||||
JavaOnlyArray keyValues = new JavaOnlyArray();
|
||||
keyValues.pushArray(getArray(keys[0], values[0]));
|
||||
keyValues.pushArray(getArray(keys[1], values[1]));
|
||||
mStorage.multiSet(keyValues, mock(Callback.class));
|
||||
|
||||
JavaOnlyArray storedKeys = new JavaOnlyArray();
|
||||
storedKeys.pushString(keys[0]);
|
||||
storedKeys.pushString(keys[1]);
|
||||
|
||||
Callback getAllCallback = mock(Callback.class);
|
||||
mStorage.getAllKeys(getAllCallback);
|
||||
verify(getAllCallback, Mockito.times(1)).invoke(null, storedKeys);
|
||||
|
||||
Callback getAllCallback2 = mock(Callback.class);
|
||||
mStorage.multiRemove(getArray(keys[0]), mock(Callback.class));
|
||||
|
||||
mStorage.getAllKeys(getAllCallback2);
|
||||
verify(getAllCallback2, Mockito.times(1)).invoke(null, getArray(keys[1]));
|
||||
|
||||
mStorage.multiRemove(getArray(keys[1]), mock(Callback.class));
|
||||
Callback getAllCallback3 = mock(Callback.class);
|
||||
mStorage.getAllKeys(getAllCallback3);
|
||||
verify(getAllCallback3, Mockito.times(1)).invoke(null, mEmptyArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear() {
|
||||
JavaOnlyArray keyValues = new JavaOnlyArray();
|
||||
keyValues.pushArray(getArray("foo", "foo2"));
|
||||
keyValues.pushArray(getArray("bar", "bar2"));
|
||||
mStorage.multiSet(keyValues, mock(Callback.class));
|
||||
|
||||
Callback clearCallback2 = mock(Callback.class);
|
||||
mStorage.clear(clearCallback2);
|
||||
verify(clearCallback2, Mockito.times(1)).invoke();
|
||||
|
||||
Callback getAllCallback2 = mock(Callback.class);
|
||||
mStorage.getAllKeys(getAllCallback2);
|
||||
verify(getAllCallback2, Mockito.times(1)).invoke(null, mEmptyArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHugeMultiGetMultiGet() {
|
||||
// Test with many keys, so that it's above the 999 limit per batch imposed by SQLite.
|
||||
final int keyCount = 1001;
|
||||
// don't set keys that divide by this magical number, so that we can check that multiGet works,
|
||||
// and returns null for missing keys
|
||||
final int magicalNumber = 343;
|
||||
|
||||
JavaOnlyArray keyValues = new JavaOnlyArray();
|
||||
for (int i = 0; i < keyCount; i++) {
|
||||
if (i % magicalNumber > 0) {
|
||||
keyValues.pushArray(getArray("key" + i, "value" + i));
|
||||
}
|
||||
}
|
||||
mStorage.multiSet(keyValues, mock(Callback.class));
|
||||
JavaOnlyArray keys = new JavaOnlyArray();
|
||||
for (int i = 0; i < keyCount; i++) {
|
||||
keys.pushString("key" + i);
|
||||
}
|
||||
mStorage.multiGet(
|
||||
keys,
|
||||
new Callback() {
|
||||
@Override
|
||||
public void invoke(Object... args) {
|
||||
assertThat(args.length).isEqualTo(2);
|
||||
JavaOnlyArray resultArray = (JavaOnlyArray) args[1];
|
||||
|
||||
assertThat(resultArray.size()).isEqualTo(keyCount);
|
||||
boolean keyReceived[] = new boolean[keyCount];
|
||||
for (int i = 0; i < keyCount; i++) {
|
||||
String key = resultArray.getArray(i).getString(0).substring(3);
|
||||
int idx = Integer.parseInt(key);
|
||||
assertThat(keyReceived[idx]).isFalse();
|
||||
keyReceived[idx] = true;
|
||||
|
||||
if (idx % magicalNumber > 0) {
|
||||
String value = resultArray.getArray(i).getString(1).substring(5);
|
||||
assertThat(key).isEqualTo(value);
|
||||
} else {
|
||||
assertThat(resultArray.getArray(i).isNull(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Test removal in same test, since it's costly to set up the test again.
|
||||
// Remove only odd keys
|
||||
JavaOnlyArray keyRemoves = new JavaOnlyArray();
|
||||
for (int i = 0; i < keyCount; i++) {
|
||||
if (i % 2 > 0) {
|
||||
keyRemoves.pushString("key" + i);
|
||||
}
|
||||
}
|
||||
mStorage.multiRemove(keyRemoves, mock(Callback.class));
|
||||
mStorage.getAllKeys(
|
||||
new Callback() {
|
||||
@Override
|
||||
public void invoke(Object... args) {
|
||||
JavaOnlyArray resultArray = (JavaOnlyArray) args[1];
|
||||
assertThat(resultArray.size()).isEqualTo(499);
|
||||
for (int i = 0; i < resultArray.size(); i++) {
|
||||
String key = resultArray.getString(i).substring(3);
|
||||
int idx = Integer.parseInt(key);
|
||||
assertThat(idx % 2).isEqualTo(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static JSONArray createJSONArray(Object... objects) {
|
||||
return new JSONArray(Arrays.asList(objects));
|
||||
}
|
||||
|
||||
private static JSONObject createJSONObject(Object... keysAndValues) {
|
||||
if (keysAndValues.length % 2 != 0) {
|
||||
throw new IllegalArgumentException("You must provide the same number of keys and values");
|
||||
}
|
||||
Map map = new HashMap();
|
||||
for (int i = 0; i < keysAndValues.length; i += 2) {
|
||||
map.put(keysAndValues[i], keysAndValues[i + 1]);
|
||||
}
|
||||
return new JSONObject(map);
|
||||
}
|
||||
|
||||
private JavaOnlyArray getArray(String... values) {
|
||||
JavaOnlyArray array = new JavaOnlyArray();
|
||||
for (String value : values) {
|
||||
array.pushString(value);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private static void waitForAsync() {
|
||||
Robolectric.flushForegroundThreadScheduler();
|
||||
Robolectric.flushBackgroundThreadScheduler();
|
||||
}
|
||||
|
||||
private static <T> T verify(T mock, VerificationMode mode) {
|
||||
waitForAsync();
|
||||
return Mockito.verify(mock, mode);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user