cleaner test API
Summary: The test mock utilities now return a promise, rather than taking a callback, which makes tests slightly nicer to read (similar to react-testing-library). No semantic changes. Reviewed By: jknoxville Differential Revision: D22186278 fbshipit-source-id: ec5b9f4e6bfeee9160e331f8c20a1d4fdcbfeede
This commit is contained in:
committed by
Facebook GitHub Bot
parent
12ac29685d
commit
83e6968fa1
@@ -46,10 +46,10 @@ class TestPlugin extends FlipperPlugin<any, any, any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test('Plugin container can render plugin and receive updates', async () => {
|
test('Plugin container can render plugin and receive updates', async () => {
|
||||||
await renderMockFlipperWithPlugin(
|
const {renderer, sendMessage, act} = await renderMockFlipperWithPlugin(
|
||||||
TestPlugin,
|
TestPlugin,
|
||||||
async ({renderer, sendMessage, act}) => {
|
);
|
||||||
expect(renderer.baseElement).toMatchInlineSnapshot(`
|
expect(renderer.baseElement).toMatchInlineSnapshot(`
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@@ -73,11 +73,9 @@ test('Plugin container can render plugin and receive updates', async () => {
|
|||||||
</body>
|
</body>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
sendMessage('inc', {delta: 2});
|
sendMessage('inc', {delta: 2});
|
||||||
});
|
});
|
||||||
|
|
||||||
expect((await renderer.findByTestId('counter')).textContent).toBe('2');
|
expect((await renderer.findByTestId('counter')).textContent).toBe('2');
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -40,24 +40,25 @@ class TestPlugin extends FlipperPlugin<any, any, any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test('can create a Fake flipper', async () => {
|
test('can create a Fake flipper', async () => {
|
||||||
await createMockFlipperWithPlugin(
|
const {
|
||||||
TestPlugin,
|
client,
|
||||||
async ({client, device, store, sendMessage}) => {
|
device,
|
||||||
expect(client).toBeTruthy();
|
store,
|
||||||
expect(device).toBeTruthy();
|
sendMessage,
|
||||||
expect(store).toBeTruthy();
|
} = await createMockFlipperWithPlugin(TestPlugin);
|
||||||
expect(sendMessage).toBeTruthy();
|
expect(client).toBeTruthy();
|
||||||
expect(client.plugins.includes(TestPlugin.id)).toBe(true);
|
expect(device).toBeTruthy();
|
||||||
expect(store.getState().connections).toMatchSnapshot();
|
expect(store).toBeTruthy();
|
||||||
expect(store.getState().plugins).toMatchSnapshot();
|
expect(sendMessage).toBeTruthy();
|
||||||
sendMessage('inc', {});
|
expect(client.plugins.includes(TestPlugin.id)).toBe(true);
|
||||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(`
|
expect(store.getState().connections).toMatchSnapshot();
|
||||||
|
expect(store.getState().plugins).toMatchSnapshot();
|
||||||
|
sendMessage('inc', {});
|
||||||
|
expect(store.getState().pluginStates).toMatchInlineSnapshot(`
|
||||||
Object {
|
Object {
|
||||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Object {
|
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Object {
|
||||||
"count": 1,
|
"count": 1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export function createStubLogger(): Logger {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
type MockFlipperCallbackArgs = {
|
type MockFlipperResult = {
|
||||||
client: Client;
|
client: Client;
|
||||||
device: BaseDevice;
|
device: BaseDevice;
|
||||||
store: Store;
|
store: Store;
|
||||||
@@ -53,8 +53,7 @@ type MockFlipperCallbackArgs = {
|
|||||||
|
|
||||||
export async function createMockFlipperWithPlugin(
|
export async function createMockFlipperWithPlugin(
|
||||||
pluginClazz: typeof FlipperPlugin,
|
pluginClazz: typeof FlipperPlugin,
|
||||||
callback: (args: MockFlipperCallbackArgs) => Promise<void>,
|
): Promise<MockFlipperResult> {
|
||||||
) {
|
|
||||||
const store = createStore(reducers);
|
const store = createStore(reducers);
|
||||||
const logger = createStubLogger();
|
const logger = createStubLogger();
|
||||||
store.dispatch(registerPlugins([pluginClazz]));
|
store.dispatch(registerPlugins([pluginClazz]));
|
||||||
@@ -134,7 +133,7 @@ export async function createMockFlipperWithPlugin(
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await callback({
|
return {
|
||||||
client,
|
client,
|
||||||
device: device as any,
|
device: device as any,
|
||||||
store,
|
store,
|
||||||
@@ -153,49 +152,46 @@ export async function createMockFlipperWithPlugin(
|
|||||||
createDevice,
|
createDevice,
|
||||||
createClient,
|
createClient,
|
||||||
logger,
|
logger,
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
type Renderer = RenderResult<typeof import('testing-library__dom/queries')>;
|
type Renderer = RenderResult<typeof import('testing-library__dom/queries')>;
|
||||||
|
|
||||||
export async function renderMockFlipperWithPlugin(
|
export async function renderMockFlipperWithPlugin(
|
||||||
pluginClazz: typeof FlipperPlugin,
|
pluginClazz: typeof FlipperPlugin,
|
||||||
callback: (
|
): Promise<
|
||||||
args: MockFlipperCallbackArgs & {
|
MockFlipperResult & {
|
||||||
renderer: Renderer;
|
renderer: Renderer;
|
||||||
act: (cb: () => void) => void;
|
act: (cb: () => void) => void;
|
||||||
},
|
}
|
||||||
) => Promise<void>,
|
> {
|
||||||
) {
|
const args = await createMockFlipperWithPlugin(pluginClazz);
|
||||||
return createMockFlipperWithPlugin(pluginClazz, async (args) => {
|
|
||||||
function selectTestPlugin(store: Store, client: Client) {
|
|
||||||
store.dispatch(
|
|
||||||
selectPlugin({
|
|
||||||
selectedPlugin: pluginClazz.id,
|
|
||||||
selectedApp: client.query.app,
|
|
||||||
deepLinkPayload: null,
|
|
||||||
selectedDevice: store.getState().connections.selectedDevice!,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
selectTestPlugin(args.store, args.client);
|
function selectTestPlugin(store: Store, client: Client) {
|
||||||
|
store.dispatch(
|
||||||
const renderer = render(
|
selectPlugin({
|
||||||
<Provider store={args.store}>
|
selectedPlugin: pluginClazz.id,
|
||||||
<PluginContainer logger={args.logger} />
|
selectedApp: client.query.app,
|
||||||
</Provider>,
|
deepLinkPayload: null,
|
||||||
|
selectedDevice: store.getState().connections.selectedDevice!,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
await callback({
|
selectTestPlugin(args.store, args.client);
|
||||||
...args,
|
|
||||||
renderer: renderer as any,
|
|
||||||
act(cb) {
|
|
||||||
testingLibAct(cb);
|
|
||||||
args.client.flushMessageBuffer();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
renderer.unmount();
|
const renderer = render(
|
||||||
});
|
<Provider store={args.store}>
|
||||||
|
<PluginContainer logger={args.logger} />
|
||||||
|
</Provider>,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...args,
|
||||||
|
renderer: renderer as any,
|
||||||
|
act(cb) {
|
||||||
|
testingLibAct(cb);
|
||||||
|
args.client.flushMessageBuffer();
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,45 +86,44 @@ function selectTestPlugin(store: Store, client: Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test('queue - events are processed immediately if plugin is selected', async () => {
|
test('queue - events are processed immediately if plugin is selected', async () => {
|
||||||
await createMockFlipperWithPlugin(
|
const {store, client, sendMessage} = await createMockFlipperWithPlugin(
|
||||||
TestPlugin,
|
TestPlugin,
|
||||||
async ({store, client, sendMessage}) => {
|
);
|
||||||
expect(store.getState().connections.selectedPlugin).toBe('TestPlugin');
|
expect(store.getState().connections.selectedPlugin).toBe('TestPlugin');
|
||||||
sendMessage('noop', {});
|
sendMessage('noop', {});
|
||||||
sendMessage('noop', {});
|
sendMessage('noop', {});
|
||||||
sendMessage('inc', {});
|
sendMessage('inc', {});
|
||||||
sendMessage('inc', {delta: 4});
|
sendMessage('inc', {delta: 4});
|
||||||
sendMessage('noop', {});
|
sendMessage('noop', {});
|
||||||
client.flushMessageBuffer();
|
client.flushMessageBuffer();
|
||||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(`
|
expect(store.getState().pluginStates).toMatchInlineSnapshot(`
|
||||||
Object {
|
Object {
|
||||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Object {
|
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Object {
|
||||||
"count": 5,
|
"count": 5,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(
|
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(
|
||||||
`Object {}`,
|
`Object {}`,
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('queue - events are NOT processed immediately if plugin is NOT selected (but enabled)', async () => {
|
test('queue - events are NOT processed immediately if plugin is NOT selected (but enabled)', async () => {
|
||||||
await createMockFlipperWithPlugin(
|
const {
|
||||||
TestPlugin,
|
store,
|
||||||
async ({client, device, store, sendMessage}) => {
|
client,
|
||||||
selectDeviceLogs(store);
|
sendMessage,
|
||||||
expect(store.getState().connections.selectedPlugin).not.toBe(
|
device,
|
||||||
'TestPlugin',
|
} = await createMockFlipperWithPlugin(TestPlugin);
|
||||||
);
|
selectDeviceLogs(store);
|
||||||
|
expect(store.getState().connections.selectedPlugin).not.toBe('TestPlugin');
|
||||||
|
|
||||||
sendMessage('inc', {});
|
sendMessage('inc', {});
|
||||||
sendMessage('inc', {delta: 2});
|
sendMessage('inc', {delta: 2});
|
||||||
sendMessage('inc', {delta: 3});
|
sendMessage('inc', {delta: 3});
|
||||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(`Object {}`);
|
expect(store.getState().pluginStates).toMatchInlineSnapshot(`Object {}`);
|
||||||
// the first message is already visible cause of the leading debounce
|
// the first message is already visible cause of the leading debounce
|
||||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
||||||
Object {
|
Object {
|
||||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
||||||
Object {
|
Object {
|
||||||
@@ -135,8 +134,8 @@ test('queue - events are NOT processed immediately if plugin is NOT selected (bu
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
client.flushMessageBuffer();
|
client.flushMessageBuffer();
|
||||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
||||||
Object {
|
Object {
|
||||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
||||||
Object {
|
Object {
|
||||||
@@ -162,68 +161,67 @@ test('queue - events are NOT processed immediately if plugin is NOT selected (bu
|
|||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
// process the message
|
// process the message
|
||||||
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
|
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
|
||||||
await processMessageQueue(TestPlugin, pluginKey, store);
|
await processMessageQueue(TestPlugin, pluginKey, store);
|
||||||
expect(store.getState().pluginStates).toEqual({
|
expect(store.getState().pluginStates).toEqual({
|
||||||
[pluginKey]: {
|
[pluginKey]: {
|
||||||
count: 6,
|
count: 6,
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(store.getState().pluginMessageQueue).toEqual({
|
|
||||||
[pluginKey]: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
// unstar, but, messages still arrives because selected
|
|
||||||
starTestPlugin(store, client);
|
|
||||||
selectTestPlugin(store, client);
|
|
||||||
sendMessage('inc', {delta: 3});
|
|
||||||
client.flushMessageBuffer();
|
|
||||||
// active, immediately processed
|
|
||||||
expect(store.getState().pluginStates).toEqual({
|
|
||||||
[pluginKey]: {
|
|
||||||
count: 9,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// different plugin, and not starred, message will never arrive
|
|
||||||
selectDeviceLogs(store);
|
|
||||||
sendMessage('inc', {delta: 4});
|
|
||||||
client.flushMessageBuffer();
|
|
||||||
expect(store.getState().pluginMessageQueue).toEqual({
|
|
||||||
[pluginKey]: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
// star again, plugin still not selected, message is queued
|
|
||||||
starTestPlugin(store, client);
|
|
||||||
sendMessage('inc', {delta: 5});
|
|
||||||
client.flushMessageBuffer();
|
|
||||||
|
|
||||||
expect(store.getState().pluginMessageQueue).toEqual({
|
|
||||||
[pluginKey]: [{api: 'TestPlugin', method: 'inc', params: {delta: 5}}],
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
);
|
});
|
||||||
|
|
||||||
|
expect(store.getState().pluginMessageQueue).toEqual({
|
||||||
|
[pluginKey]: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
// unstar, but, messages still arrives because selected
|
||||||
|
starTestPlugin(store, client);
|
||||||
|
selectTestPlugin(store, client);
|
||||||
|
sendMessage('inc', {delta: 3});
|
||||||
|
client.flushMessageBuffer();
|
||||||
|
// active, immediately processed
|
||||||
|
expect(store.getState().pluginStates).toEqual({
|
||||||
|
[pluginKey]: {
|
||||||
|
count: 9,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// different plugin, and not starred, message will never arrive
|
||||||
|
selectDeviceLogs(store);
|
||||||
|
sendMessage('inc', {delta: 4});
|
||||||
|
client.flushMessageBuffer();
|
||||||
|
expect(store.getState().pluginMessageQueue).toEqual({
|
||||||
|
[pluginKey]: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
// star again, plugin still not selected, message is queued
|
||||||
|
starTestPlugin(store, client);
|
||||||
|
sendMessage('inc', {delta: 5});
|
||||||
|
client.flushMessageBuffer();
|
||||||
|
|
||||||
|
expect(store.getState().pluginMessageQueue).toEqual({
|
||||||
|
[pluginKey]: [{api: 'TestPlugin', method: 'inc', params: {delta: 5}}],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('queue - events are queued for plugins that are favorite when app is not selected', async () => {
|
test('queue - events are queued for plugins that are favorite when app is not selected', async () => {
|
||||||
await createMockFlipperWithPlugin(
|
const {
|
||||||
TestPlugin,
|
device,
|
||||||
async ({device, store, sendMessage, createClient}) => {
|
store,
|
||||||
selectDeviceLogs(store);
|
sendMessage,
|
||||||
expect(store.getState().connections.selectedPlugin).not.toBe(
|
createClient,
|
||||||
'TestPlugin',
|
} = await createMockFlipperWithPlugin(TestPlugin);
|
||||||
);
|
selectDeviceLogs(store);
|
||||||
|
expect(store.getState().connections.selectedPlugin).not.toBe('TestPlugin');
|
||||||
|
|
||||||
const client2 = createClient(device, 'TestApp2');
|
const client2 = createClient(device, 'TestApp2');
|
||||||
store.dispatch(selectClient(client2.id));
|
store.dispatch(selectClient(client2.id));
|
||||||
|
|
||||||
// Now we send a message to the second client, it should arrive,
|
// Now we send a message to the second client, it should arrive,
|
||||||
// as the plugin was enabled already on the first client as well
|
// as the plugin was enabled already on the first client as well
|
||||||
sendMessage('inc', {delta: 2});
|
sendMessage('inc', {delta: 2});
|
||||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(`Object {}`);
|
expect(store.getState().pluginStates).toMatchInlineSnapshot(`Object {}`);
|
||||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
||||||
Object {
|
Object {
|
||||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
||||||
Object {
|
Object {
|
||||||
@@ -236,29 +234,29 @@ test('queue - events are queued for plugins that are favorite when app is not se
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('queue - events are queued for plugins that are favorite when app is selected on different device', async () => {
|
test('queue - events are queued for plugins that are favorite when app is selected on different device', async () => {
|
||||||
await createMockFlipperWithPlugin(
|
const {
|
||||||
TestPlugin,
|
client,
|
||||||
async ({client, store, sendMessage, createDevice, createClient}) => {
|
store,
|
||||||
selectDeviceLogs(store);
|
sendMessage,
|
||||||
expect(store.getState().connections.selectedPlugin).not.toBe(
|
createDevice,
|
||||||
'TestPlugin',
|
createClient,
|
||||||
);
|
} = await createMockFlipperWithPlugin(TestPlugin);
|
||||||
|
selectDeviceLogs(store);
|
||||||
|
expect(store.getState().connections.selectedPlugin).not.toBe('TestPlugin');
|
||||||
|
|
||||||
const device2 = createDevice('serial2');
|
const device2 = createDevice('serial2');
|
||||||
const client2 = createClient(device2, client.query.app); // same app id
|
const client2 = createClient(device2, client.query.app); // same app id
|
||||||
store.dispatch(selectDevice(device2));
|
store.dispatch(selectDevice(device2));
|
||||||
store.dispatch(selectClient(client2.id));
|
store.dispatch(selectClient(client2.id));
|
||||||
|
|
||||||
// Now we send a message to the second client, it should arrive,
|
// Now we send a message to the second client, it should arrive,
|
||||||
// as the plugin was enabled already on the first client as well
|
// as the plugin was enabled already on the first client as well
|
||||||
sendMessage('inc', {delta: 2});
|
sendMessage('inc', {delta: 2});
|
||||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(`Object {}`);
|
expect(store.getState().pluginStates).toMatchInlineSnapshot(`Object {}`);
|
||||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
||||||
Object {
|
Object {
|
||||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
||||||
Object {
|
Object {
|
||||||
@@ -271,180 +269,164 @@ test('queue - events are queued for plugins that are favorite when app is select
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('queue - events processing will be paused', async () => {
|
test('queue - events processing will be paused', async () => {
|
||||||
await createMockFlipperWithPlugin(
|
const {
|
||||||
TestPlugin,
|
client,
|
||||||
async ({client, device, store, sendMessage}) => {
|
device,
|
||||||
selectDeviceLogs(store);
|
store,
|
||||||
|
sendMessage,
|
||||||
|
} = await createMockFlipperWithPlugin(TestPlugin);
|
||||||
|
selectDeviceLogs(store);
|
||||||
|
|
||||||
sendMessage('inc', {});
|
sendMessage('inc', {});
|
||||||
sendMessage('inc', {delta: 3});
|
sendMessage('inc', {delta: 3});
|
||||||
sendMessage('inc', {delta: 5});
|
sendMessage('inc', {delta: 5});
|
||||||
client.flushMessageBuffer();
|
client.flushMessageBuffer();
|
||||||
|
|
||||||
// process the message
|
// process the message
|
||||||
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
|
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
|
||||||
|
|
||||||
// controlled idler will signal and and off that idling is needed
|
// controlled idler will signal and and off that idling is needed
|
||||||
const idler = new TestIdler();
|
const idler = new TestIdler();
|
||||||
|
|
||||||
const p = processMessageQueue(
|
const p = processMessageQueue(TestPlugin, pluginKey, store, undefined, idler);
|
||||||
TestPlugin,
|
|
||||||
pluginKey,
|
|
||||||
store,
|
|
||||||
undefined,
|
|
||||||
idler,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(store.getState().pluginStates).toEqual({
|
expect(store.getState().pluginStates).toEqual({
|
||||||
[pluginKey]: {
|
[pluginKey]: {
|
||||||
count: 4,
|
count: 4,
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(store.getState().pluginMessageQueue).toEqual({
|
|
||||||
[pluginKey]: [{api: 'TestPlugin', method: 'inc', params: {delta: 5}}],
|
|
||||||
});
|
|
||||||
|
|
||||||
await idler.next();
|
|
||||||
expect(store.getState().pluginStates).toEqual({
|
|
||||||
[pluginKey]: {
|
|
||||||
count: 9,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(store.getState().pluginMessageQueue).toEqual({
|
|
||||||
[pluginKey]: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
// don't idle anymore
|
|
||||||
idler.run();
|
|
||||||
await p;
|
|
||||||
},
|
},
|
||||||
);
|
});
|
||||||
|
|
||||||
|
expect(store.getState().pluginMessageQueue).toEqual({
|
||||||
|
[pluginKey]: [{api: 'TestPlugin', method: 'inc', params: {delta: 5}}],
|
||||||
|
});
|
||||||
|
|
||||||
|
await idler.next();
|
||||||
|
expect(store.getState().pluginStates).toEqual({
|
||||||
|
[pluginKey]: {
|
||||||
|
count: 9,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(store.getState().pluginMessageQueue).toEqual({
|
||||||
|
[pluginKey]: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
// don't idle anymore
|
||||||
|
idler.run();
|
||||||
|
await p;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('queue - messages that arrive during processing will be queued', async () => {
|
test('queue - messages that arrive during processing will be queued', async () => {
|
||||||
await createMockFlipperWithPlugin(
|
const {
|
||||||
TestPlugin,
|
client,
|
||||||
async ({client, device, store, sendMessage}) => {
|
device,
|
||||||
selectDeviceLogs(store);
|
store,
|
||||||
|
sendMessage,
|
||||||
|
} = await createMockFlipperWithPlugin(TestPlugin);
|
||||||
|
selectDeviceLogs(store);
|
||||||
|
|
||||||
sendMessage('inc', {});
|
sendMessage('inc', {});
|
||||||
sendMessage('inc', {delta: 2});
|
sendMessage('inc', {delta: 2});
|
||||||
sendMessage('inc', {delta: 3});
|
sendMessage('inc', {delta: 3});
|
||||||
client.flushMessageBuffer();
|
client.flushMessageBuffer();
|
||||||
|
|
||||||
// process the message
|
// process the message
|
||||||
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
|
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
|
||||||
|
|
||||||
const idler = new TestIdler();
|
const idler = new TestIdler();
|
||||||
|
|
||||||
const p = processMessageQueue(
|
const p = processMessageQueue(TestPlugin, pluginKey, store, undefined, idler);
|
||||||
TestPlugin,
|
|
||||||
pluginKey,
|
|
||||||
store,
|
|
||||||
undefined,
|
|
||||||
idler,
|
|
||||||
);
|
|
||||||
|
|
||||||
// first message is consumed
|
// first message is consumed
|
||||||
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(1);
|
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(1);
|
||||||
expect(store.getState().pluginStates[pluginKey].count).toBe(3);
|
expect(store.getState().pluginStates[pluginKey].count).toBe(3);
|
||||||
|
|
||||||
// Select the current plugin as active, still, messages should end up in the queue
|
// Select the current plugin as active, still, messages should end up in the queue
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
selectPlugin({
|
selectPlugin({
|
||||||
selectedPlugin: TestPlugin.id,
|
selectedPlugin: TestPlugin.id,
|
||||||
selectedApp: client.id,
|
selectedApp: client.id,
|
||||||
deepLinkPayload: null,
|
deepLinkPayload: null,
|
||||||
selectedDevice: device,
|
selectedDevice: device,
|
||||||
}),
|
}),
|
||||||
);
|
|
||||||
expect(store.getState().connections.selectedPlugin).toBe('TestPlugin');
|
|
||||||
|
|
||||||
sendMessage('inc', {delta: 4});
|
|
||||||
client.flushMessageBuffer();
|
|
||||||
// should not be processed yet
|
|
||||||
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(2);
|
|
||||||
expect(store.getState().pluginStates[pluginKey].count).toBe(3);
|
|
||||||
|
|
||||||
await idler.next();
|
|
||||||
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(0);
|
|
||||||
expect(store.getState().pluginStates[pluginKey].count).toBe(10);
|
|
||||||
|
|
||||||
idler.run();
|
|
||||||
await p;
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
expect(store.getState().connections.selectedPlugin).toBe('TestPlugin');
|
||||||
|
|
||||||
|
sendMessage('inc', {delta: 4});
|
||||||
|
client.flushMessageBuffer();
|
||||||
|
// should not be processed yet
|
||||||
|
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(2);
|
||||||
|
expect(store.getState().pluginStates[pluginKey].count).toBe(3);
|
||||||
|
|
||||||
|
await idler.next();
|
||||||
|
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(0);
|
||||||
|
expect(store.getState().pluginStates[pluginKey].count).toBe(10);
|
||||||
|
|
||||||
|
idler.run();
|
||||||
|
await p;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('queue - processing can be cancelled', async () => {
|
test('queue - processing can be cancelled', async () => {
|
||||||
await createMockFlipperWithPlugin(
|
const {
|
||||||
TestPlugin,
|
client,
|
||||||
async ({client, device, store, sendMessage}) => {
|
device,
|
||||||
selectDeviceLogs(store);
|
store,
|
||||||
|
sendMessage,
|
||||||
|
} = await createMockFlipperWithPlugin(TestPlugin);
|
||||||
|
selectDeviceLogs(store);
|
||||||
|
|
||||||
sendMessage('inc', {});
|
sendMessage('inc', {});
|
||||||
sendMessage('inc', {delta: 2});
|
sendMessage('inc', {delta: 2});
|
||||||
sendMessage('inc', {delta: 3});
|
sendMessage('inc', {delta: 3});
|
||||||
sendMessage('inc', {delta: 4});
|
sendMessage('inc', {delta: 4});
|
||||||
sendMessage('inc', {delta: 5});
|
sendMessage('inc', {delta: 5});
|
||||||
client.flushMessageBuffer();
|
client.flushMessageBuffer();
|
||||||
|
|
||||||
// process the message
|
// process the message
|
||||||
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
|
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
|
||||||
|
|
||||||
const idler = new TestIdler();
|
const idler = new TestIdler();
|
||||||
|
|
||||||
const p = processMessageQueue(
|
const p = processMessageQueue(TestPlugin, pluginKey, store, undefined, idler);
|
||||||
TestPlugin,
|
|
||||||
pluginKey,
|
|
||||||
store,
|
|
||||||
undefined,
|
|
||||||
idler,
|
|
||||||
);
|
|
||||||
|
|
||||||
// first message is consumed
|
// first message is consumed
|
||||||
await idler.next();
|
await idler.next();
|
||||||
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(1);
|
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(1);
|
||||||
expect(store.getState().pluginStates[pluginKey].count).toBe(10);
|
expect(store.getState().pluginStates[pluginKey].count).toBe(10);
|
||||||
|
|
||||||
idler.cancel();
|
idler.cancel();
|
||||||
|
|
||||||
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(1);
|
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(1);
|
||||||
expect(store.getState().pluginStates[pluginKey].count).toBe(10);
|
expect(store.getState().pluginStates[pluginKey].count).toBe(10);
|
||||||
await p;
|
await p;
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('queue - make sure resetting plugin state clears the message queue', async () => {
|
test('queue - make sure resetting plugin state clears the message queue', async () => {
|
||||||
await createMockFlipperWithPlugin(
|
const {
|
||||||
TestPlugin,
|
client,
|
||||||
async ({client, device, store, sendMessage}) => {
|
device,
|
||||||
selectDeviceLogs(store);
|
store,
|
||||||
|
sendMessage,
|
||||||
|
} = await createMockFlipperWithPlugin(TestPlugin);
|
||||||
|
selectDeviceLogs(store);
|
||||||
|
|
||||||
sendMessage('inc', {});
|
sendMessage('inc', {});
|
||||||
sendMessage('inc', {delta: 2});
|
sendMessage('inc', {delta: 2});
|
||||||
client.flushMessageBuffer();
|
client.flushMessageBuffer();
|
||||||
|
|
||||||
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
|
const pluginKey = getPluginKey(client.id, device, TestPlugin.id);
|
||||||
|
|
||||||
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(2);
|
expect(store.getState().pluginMessageQueue[pluginKey].length).toBe(2);
|
||||||
|
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: 'CLEAR_PLUGIN_STATE',
|
type: 'CLEAR_PLUGIN_STATE',
|
||||||
payload: {clientId: client.id, devicePlugins: new Set()},
|
payload: {clientId: client.id, devicePlugins: new Set()},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(store.getState().pluginMessageQueue[pluginKey]).toBe(undefined);
|
expect(store.getState().pluginMessageQueue[pluginKey]).toBe(undefined);
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('queue will be cleaned up when it exceeds maximum size', () => {
|
test('queue will be cleaned up when it exceeds maximum size', () => {
|
||||||
@@ -494,31 +476,34 @@ test('client - incoming messages are buffered and flushed together', async () =>
|
|||||||
static persistedStateReducer = jest.fn();
|
static persistedStateReducer = jest.fn();
|
||||||
}
|
}
|
||||||
|
|
||||||
await createMockFlipperWithPlugin(
|
const {
|
||||||
TestPlugin,
|
client,
|
||||||
async ({client, store, device, sendMessage}) => {
|
store,
|
||||||
selectDeviceLogs(store);
|
device,
|
||||||
|
sendMessage,
|
||||||
|
} = await createMockFlipperWithPlugin(TestPlugin);
|
||||||
|
selectDeviceLogs(store);
|
||||||
|
|
||||||
store.dispatch(registerPlugins([StubDeviceLogs]));
|
store.dispatch(registerPlugins([StubDeviceLogs]));
|
||||||
sendMessage('inc', {});
|
sendMessage('inc', {});
|
||||||
sendMessage('inc', {delta: 2});
|
sendMessage('inc', {delta: 2});
|
||||||
sendMessage('inc', {delta: 3});
|
sendMessage('inc', {delta: 3});
|
||||||
|
|
||||||
// send a message to device logs
|
// send a message to device logs
|
||||||
client.onMessage(
|
client.onMessage(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
method: 'execute',
|
method: 'execute',
|
||||||
params: {
|
params: {
|
||||||
api: 'DevicePlugin',
|
api: 'DevicePlugin',
|
||||||
method: 'log',
|
method: 'log',
|
||||||
params: {line: 'suff'},
|
params: {line: 'suff'},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(store.getState().pluginStates).toMatchInlineSnapshot(`Object {}`);
|
expect(store.getState().pluginStates).toMatchInlineSnapshot(`Object {}`);
|
||||||
// the first message is already visible cause of the leading debounce
|
// the first message is already visible cause of the leading debounce
|
||||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
||||||
Object {
|
Object {
|
||||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
||||||
Object {
|
Object {
|
||||||
@@ -529,7 +514,7 @@ test('client - incoming messages are buffered and flushed together', async () =>
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
expect(client.messageBuffer).toMatchInlineSnapshot(`
|
expect(client.messageBuffer).toMatchInlineSnapshot(`
|
||||||
Object {
|
Object {
|
||||||
"TestApp#Android#MockAndroidDevice#serial#DevicePlugin": Object {
|
"TestApp#Android#MockAndroidDevice#serial#DevicePlugin": Object {
|
||||||
"messages": Array [
|
"messages": Array [
|
||||||
@@ -565,8 +550,8 @@ test('client - incoming messages are buffered and flushed together', async () =>
|
|||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
await sleep(500);
|
await sleep(500);
|
||||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
||||||
Object {
|
Object {
|
||||||
"TestApp#Android#MockAndroidDevice#serial#DevicePlugin": Array [
|
"TestApp#Android#MockAndroidDevice#serial#DevicePlugin": Array [
|
||||||
Object {
|
Object {
|
||||||
@@ -600,17 +585,17 @@ test('client - incoming messages are buffered and flushed together', async () =>
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
expect(client.messageBuffer).toMatchInlineSnapshot(`Object {}`);
|
expect(client.messageBuffer).toMatchInlineSnapshot(`Object {}`);
|
||||||
expect(
|
expect(StubDeviceLogs.persistedStateReducer.mock.calls).toMatchInlineSnapshot(
|
||||||
StubDeviceLogs.persistedStateReducer.mock.calls,
|
`Array []`,
|
||||||
).toMatchInlineSnapshot(`Array []`);
|
);
|
||||||
|
|
||||||
// tigger processing the queue
|
// tigger processing the queue
|
||||||
const pluginKey = getPluginKey(client.id, device, StubDeviceLogs.id);
|
const pluginKey = getPluginKey(client.id, device, StubDeviceLogs.id);
|
||||||
await processMessageQueue(StubDeviceLogs, pluginKey, store);
|
await processMessageQueue(StubDeviceLogs, pluginKey, store);
|
||||||
|
|
||||||
expect(StubDeviceLogs.persistedStateReducer.mock.calls)
|
expect(StubDeviceLogs.persistedStateReducer.mock.calls)
|
||||||
.toMatchInlineSnapshot(`
|
.toMatchInlineSnapshot(`
|
||||||
Array [
|
Array [
|
||||||
Array [
|
Array [
|
||||||
Object {},
|
Object {},
|
||||||
@@ -622,7 +607,7 @@ test('client - incoming messages are buffered and flushed together', async () =>
|
|||||||
]
|
]
|
||||||
`);
|
`);
|
||||||
|
|
||||||
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
expect(store.getState().pluginMessageQueue).toMatchInlineSnapshot(`
|
||||||
Object {
|
Object {
|
||||||
"TestApp#Android#MockAndroidDevice#serial#DevicePlugin": Array [],
|
"TestApp#Android#MockAndroidDevice#serial#DevicePlugin": Array [],
|
||||||
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
"TestApp#Android#MockAndroidDevice#serial#TestPlugin": Array [
|
||||||
@@ -648,6 +633,4 @@ test('client - incoming messages are buffered and flushed together', async () =>
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user