NativePlugins API update
Summary: The main change is is changing from the inheritance model: `FlipperPlugin > NativePlugin > TablePlugin > ConcretePlugin` to a composition model where: `NativePlugin > TablePlugin > ConcretePlugin` And behind the scenes, there's a `FlipperPlugin` that has a `NativePlugin` reference. Now your native plugin will call methods like (in the table case) `display.updateRows` instead of `super.updateRows()` The reasons for this are: * Testability: we can easily mock the display and assert output. * Encapsulation: Previously, native plugins could call `mConnection.send(...)` and send completely unsupported messages to the desktop. Now they only have access to the display's public api, which is guaranteed to work. I've also changed it so that on every row update, we send the latest table metadata along with it. This makes sure we can ensure that the right table schema is displayed for the current data. QueryResponder interface also added, which will come in useful for queryable datasets. Reviewed By: passy Differential Revision: D14751885 fbshipit-source-id: ea0bbd25f7eaa60020f8866fe210d8bd1c22e90b
This commit is contained in:
committed by
Facebook Github Bot
parent
703f43a903
commit
fa3dcdc5dd
@@ -0,0 +1,14 @@
|
||||
package com.facebook.flipper.nativeplugins.table;
|
||||
|
||||
public class MockTablePlugin extends TablePlugin {
|
||||
|
||||
@Override
|
||||
public TableMetadata getMetadata() {
|
||||
return new TableMetadata.Builder().columns().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Mock Table Plugin";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.facebook.flipper.nativeplugins.table;
|
||||
|
||||
import com.facebook.flipper.nativeplugins.components.Sidebar;
|
||||
import java.util.Map;
|
||||
|
||||
public class MockTableRow extends TableRow {
|
||||
public MockTableRow(String id, Map<Column, ? extends Value> values, Sidebar sidebar) {
|
||||
super(id, values, sidebar);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.facebook.flipper.nativeplugins.table;
|
||||
|
||||
public class TableMetadataTestUtils {
|
||||
|
||||
public static Column[] getColumns(TableMetadata tableMetadata) {
|
||||
return tableMetadata.mColumns;
|
||||
}
|
||||
|
||||
public static QueryableTableRowProvider getQueryResponder(TableMetadata tableMetadata) {
|
||||
return tableMetadata.responder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.facebook.flipper.nativeplugins.table;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import com.facebook.flipper.core.FlipperArray;
|
||||
import com.facebook.flipper.core.FlipperObject;
|
||||
import com.facebook.flipper.nativeplugins.components.Sidebar;
|
||||
import com.facebook.flipper.testing.FlipperConnectionMock;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class TableRowDisplayImplTest {
|
||||
|
||||
FlipperConnectionMock mConnection;
|
||||
MockTablePlugin mockTablePlugin;
|
||||
|
||||
static final Column NAME_COLUMN =
|
||||
new Column.Builder("name")
|
||||
.displayName("Name")
|
||||
.displayWidthPercent(90)
|
||||
.isFilterable(true)
|
||||
.showByDefault(false)
|
||||
.build();
|
||||
static final Column AGE_COLUMN =
|
||||
new Column.Builder("age")
|
||||
.displayName("Age")
|
||||
.displayWidthPercent(50)
|
||||
.isFilterable(false)
|
||||
.showByDefault(true)
|
||||
.build();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
mConnection = new FlipperConnectionMock();
|
||||
mockTablePlugin = new MockTablePlugin();
|
||||
}
|
||||
|
||||
private TableRow row(String id, String name, int age) {
|
||||
Map<Column, TableRow.Value> map1 = new HashMap<>();
|
||||
map1.put(NAME_COLUMN, new TableRow.StringValue(name));
|
||||
map1.put(AGE_COLUMN, new TableRow.IntValue(age));
|
||||
return new MockTableRow(id, map1, new Sidebar());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRow() {
|
||||
TableRowDisplay display = new TableRowDisplayImpl(mConnection, mockTablePlugin);
|
||||
display.updateRow(row("row1", "santa", 55), null);
|
||||
|
||||
assertEquals(1, mConnection.sent.get("updateRows").size());
|
||||
FlipperArray rowArray = (FlipperArray) mConnection.sent.get("updateRows").get(0);
|
||||
assertEquals(1, rowArray.length());
|
||||
FlipperObject updatedRow = rowArray.getObject(0);
|
||||
assertEquals(serializedRow("row1", "santa", 55), updatedRow);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRows() {
|
||||
TableRowDisplay display = new TableRowDisplayImpl(mConnection, mockTablePlugin);
|
||||
List<TableRow> rows = new ArrayList<>();
|
||||
rows.add(row("row1", "santa", 55));
|
||||
rows.add(row("row2", "elf", 15));
|
||||
display.updateRows(rows, null);
|
||||
|
||||
assertEquals(1, mConnection.sent.get("updateRows").size());
|
||||
FlipperArray rowArray = (FlipperArray) mConnection.sent.get("updateRows").get(0);
|
||||
assertEquals(2, rowArray.length());
|
||||
assertEquals(serializedRow("row1", "santa", 55), rowArray.getObject(0));
|
||||
assertEquals(serializedRow("row2", "elf", 15), rowArray.getObject(1));
|
||||
}
|
||||
|
||||
private FlipperObject serializedRow(String id, String name, int age) {
|
||||
return new FlipperObject(
|
||||
"{\"columns\":{\"name\":{\"type\":\"string\",\"value\":\""
|
||||
+ name
|
||||
+ "\"},\"id\":\""
|
||||
+ id
|
||||
+ "\",\"age\":{\"type\":\"int\",\"value\":"
|
||||
+ age
|
||||
+ "}},\"sidebar\":[],\"id\":\""
|
||||
+ id
|
||||
+ "\"}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user