Added multi-test setup logic

This commit is contained in:
Brian Vaughn
2019-04-11 09:07:40 -07:00
parent 7621df5baf
commit 9fb794b6ed
11 changed files with 142 additions and 92 deletions

View File

@@ -8,5 +8,9 @@
},
"settings": {
"version": "detect"
},
"globals": {
"__DEV__": "readonly",
"jasmine": "readonly"
}
}

View File

@@ -9,3 +9,12 @@ declare module 'events' {
declare export default typeof EventEmitter;
}
declare var __DEV__: boolean;
declare var jasmine: {|
getEnv: () => {|
afterEach: (callback: Function) => void,
beforeEach: (callback: Function) => void,
|},
|};

View File

@@ -16,6 +16,12 @@
"moduleNameMapper": {
"^src/(.*)$": "<rootDir>/src/$1"
},
"setupFiles": [
"<rootDir>/src/__tests__/setupEnv"
],
"setupFilesAfterEnv": [
"<rootDir>/src/__tests__/setupTests"
],
"snapshotSerializers": [
"<rootDir>/src/__tests__/storeSerializer"
],

View File

@@ -1,11 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`sanity should pass 1`] = `
▾ <Grandparent>
▾ <Parent>
<Child key="one">
<Child key="two">
▾ <Parent>
<Child key="one">
<Child key="two">
`;

View File

@@ -0,0 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Store should initialize a multiple root tree 1`] = `
▾ <Parent>
<Child key="one">
<Child key="two">
▾ <Parent>
<Child key="one">
<Child key="two">
`;
exports[`Store should initialize a simple tree 1`] = `
▾ <Grandparent>
▾ <Parent>
<Child key="one">
<Child key="two">
▾ <Parent>
<Child key="one">
<Child key="two">
`;

View File

@@ -1,41 +0,0 @@
// @flow
import { setup } from './utils';
describe('sanity', () => {
let React;
let ReactDOM;
let store;
beforeEach(() => {
store = setup();
React = require('react');
ReactDOM = require('react-dom');
});
it('should pass', () => {
function Grandparent() {
return (
<React.Fragment>
<Parent />
<Parent />
</React.Fragment>
);
}
function Parent() {
return [<Child key="one" />, <Child key="two" />];
}
function Child() {
return <div>Hi!</div>;
}
ReactDOM.render(<Grandparent />, document.createElement('div'));
jest.runAllTimers(); // Flush Bridge operations
expect(store).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,7 @@
// @flow
global.localStorage = {
getItem: jest.fn(),
setItem: jest.fn(),
clear: jest.fn(),
};

View File

@@ -0,0 +1,50 @@
// @flow
import Agent from 'src/backend/agent';
import { initBackend } from 'src/backend';
import Bridge from 'src/bridge';
import Store from 'src/devtools/store';
import { installHook } from 'src/hook';
let agent;
let bridge;
let bridgeListeners;
// Mimic the global we set with Webpack's DefinePlugin
global.__DEV__ = process.env.NODE_ENV !== 'production';
const env = jasmine.getEnv();
env.beforeEach(() => {
// It's important to reset modules between test runs;
// Without this, ReactDOM won't re-inject itself into the new hook.
jest.resetModules();
// Fake timers let us flush Bridge operations between setup and assertions.
jest.useFakeTimers();
installHook(global);
bridgeListeners = [];
bridge = new Bridge(
{
listen(callback) {
bridgeListeners.push(callback);
},
send(event: string, payload: any, transferable?: Array<any>) {
bridgeListeners.forEach(callback => callback({ event, payload }));
},
},
{ batchDuration: 0 }
);
agent = new Agent();
agent.addBridge(bridge);
initBackend(global.__REACT_DEVTOOLS_GLOBAL_HOOK__, agent, global);
global.store = new Store(bridge);
});
env.afterEach(() => {
delete global.__REACT_DEVTOOLS_GLOBAL_HOOK__;
});

View File

@@ -0,0 +1,43 @@
// @flow
describe('Store', () => {
let React;
let ReactDOM;
let store;
beforeEach(() => {
store = global.store;
React = require('react');
ReactDOM = require('react-dom');
});
it('should initialize a simple tree', () => {
const Grandparent = () => (
<React.Fragment>
<Parent />
<Parent />
</React.Fragment>
);
const Parent = () => [<Child key="one" />, <Child key="two" />];
const Child = () => <div>Hi!</div>;
ReactDOM.render(<Grandparent />, document.createElement('div'));
jest.runAllTimers(); // Flush Bridge operations
expect(store).toMatchSnapshot();
});
it('should initialize a multiple root tree', () => {
const Parent = () => [<Child key="one" />, <Child key="two" />];
const Child = () => <div>Hi!</div>;
ReactDOM.render(<Parent />, document.createElement('div'));
ReactDOM.render(<Parent />, document.createElement('div'));
jest.runAllTimers(); // Flush Bridge operations
expect(store).toMatchSnapshot();
});
});

View File

@@ -1,40 +0,0 @@
// @flow
import Agent from 'src/backend/agent';
import { initBackend } from 'src/backend';
import Bridge from 'src/bridge';
import Store from 'src/devtools/store';
import { installHook } from 'src/hook';
export function setup(): Store {
installHook(global);
jest.useFakeTimers();
// TODO Replace this with a polyfill?
global.localStorage = {
getItem: jest.fn(),
setItem: jest.fn(),
clear: jest.fn(),
};
const listeners = [];
const bridge = new Bridge(
{
listen(callback) {
listeners.push(callback);
},
send(event: string, payload: any, transferable?: Array<any>) {
listeners.forEach(callback => callback({ event, payload }));
},
},
{ batchDuration: 0 }
);
const agent = new Agent();
agent.addBridge(bridge);
initBackend(global.__REACT_DEVTOOLS_GLOBAL_HOOK__, agent, global);
return new Store(bridge);
}

View File

@@ -189,6 +189,9 @@ export function installHook(target: any): DevToolsHook | null {
target,
'__REACT_DEVTOOLS_GLOBAL_HOOK__',
({
// This property needs to be configurable for the test environment,
// else we won't be able to delete and recreate it beween tests.
configurable: __DEV__,
enumerable: false,
get() {
return hook;