Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Petterh/support parcelable array args #26379

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.facebook.react.bridge;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.NonNull;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import com.facebook.soloader.SoLoader;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import static com.facebook.react.bridge.Arguments.fromBundle;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

@RunWith(AndroidJUnit4.class)
public class ArgumentsTest {

@Before
public void setUp() {
Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
SoLoader.init(context, false);
}

@Test
public void testFromBundle() {
verifyBundle(createBundle());
}

/**
* When passing a bundle via {@link Intent} extras, it gets parceled and unparceled.
* Any array of bundles will return as an array of {@link Parcelable} instead. This test
* verifies that {@link Arguments#fromArray} handles this situation correctly.
*/
@Test
public void testFromMarshaledBundle() {
verifyBundle(marshalAndUnmarshalBundle(createBundle()));
}

private void verifyBundle(@NonNull Bundle bundle) {
WritableMap map = fromBundle(bundle);
assertNotNull(map);

assertEquals(ReadableType.Array, map.getType("children"));
ReadableArray children = map.getArray("children");
assertNotNull(children);
assertEquals(1, children.size());

assertEquals(ReadableType.Map, children.getType(0));
ReadableMap child = children.getMap(0);
assertNotNull(child);
assertEquals("exampleChild", child.getString("exampleChildKey"));
}

@NonNull
private Bundle marshalAndUnmarshalBundle(@NonNull Bundle bundle) {
Parcel parcel = null;
try {
parcel = Parcel.obtain();
bundle.writeToParcel(parcel, 0);

byte[] bytes = parcel.marshall();
parcel.unmarshall(bytes, 0, bytes.length);
parcel.setDataPosition(0);
return Bundle.CREATOR.createFromParcel(parcel);
} finally {
if (parcel != null) {
parcel.recycle();
}
}
}

@NonNull
private Bundle createBundle() {
Bundle bundle = new Bundle();
Bundle[] children = new Bundle[1];
children[0] = new Bundle();
children[0].putString("exampleChildKey", "exampleChild");
bundle.putSerializable("children", children);
return bundle;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
package com.facebook.react.bridge;

import android.os.Bundle;
import android.os.Parcelable;

import androidx.annotation.Nullable;
import java.lang.reflect.Array;
import java.util.AbstractList;
Expand Down Expand Up @@ -218,6 +220,14 @@ public static WritableArray fromArray(Object array) {
for (boolean v : (boolean[]) array) {
catalystArray.pushBoolean(v);
}
} else if (array instanceof Parcelable[]) {
for (Parcelable v : (Parcelable[]) array) {
if (v instanceof Bundle) {
catalystArray.pushMap(fromBundle((Bundle) v));
} else {
throw new IllegalArgumentException("Unexpected array member type " + v.getClass());
}
}
} else {
throw new IllegalArgumentException("Unknown array type " + array.getClass());
}
Expand Down