This commit is contained in:
Nathan Bierema 2020-08-09 20:33:29 -04:00
parent 7924f32f3e
commit 92675e1fba
7 changed files with 145 additions and 141 deletions

View File

@ -47,8 +47,8 @@ render(
<ConnectedRouter history={history}> <ConnectedRouter history={history}>
<Route path={ROOT}> <Route path={ROOT}>
<DemoApp /> <DemoApp />
{!useDevtoolsExtension && <ConnectedDevTools />}
</Route> </Route>
{!useDevtoolsExtension && <ConnectedDevTools />}
</ConnectedRouter> </ConnectedRouter>
</Provider>, </Provider>,
document.getElementById('root') document.getElementById('root')

View File

@ -26,7 +26,7 @@ const ROOT = '/'; // process.env.NODE_ENV === 'production' ? '/' : '/';
class DemoApp extends React.Component { class DemoApp extends React.Component {
render() { render() {
const options = getOptions(); const options = getOptions(this.props.router.location);
return ( return (
<div style={styles.wrapper}> <div style={styles.wrapper}>

View File

@ -0,0 +1,42 @@
import React from 'react';
import { connect } from 'react-redux';
import { createDevTools } from 'redux-devtools';
import DevtoolsInspector from 'redux-devtools-inspector';
import DockMonitor from 'redux-devtools-dock-monitor';
import getOptions from './getOptions';
import TestGenerator from '../../../src';
export const getDevTools = (location) =>
createDevTools(
<DockMonitor
defaultIsVisible
toggleVisibilityKey="ctrl-h"
changePositionKey="ctrl-q"
changeMonitorKey="ctrl-m"
>
<DevtoolsInspector
theme={getOptions(location).theme}
shouldPersistState
invertTheme={!getOptions(location).dark}
supportImmutable={getOptions(location).supportImmutable}
tabs={(defaultTabs) => [
{
name: 'Test',
component: TestGenerator,
},
...defaultTabs,
]}
/>
</DockMonitor>
);
const UnconnectedDevTools = ({ location }) => {
const DevTools = getDevTools(location);
return <DevTools />;
};
const mapStateToProps = (state) => ({
location: state.router.location,
});
export const ConnectedDevTools = connect(mapStateToProps)(UnconnectedDevTools);

View File

@ -1,11 +1,11 @@
export default function getOptions() { export default function getOptions(location) {
return { return {
useExtension: window.location.search.indexOf('ext') !== -1, useExtension: location.search.indexOf('ext') !== -1,
supportImmutable: window.location.search.indexOf('immutable') !== -1, supportImmutable: location.search.indexOf('immutable') !== -1,
theme: do { theme: do {
const match = window.location.search.match(/theme=([^&]+)/); const match = location.search.match(/theme=([^&]+)/);
match ? match[1] : 'inspector'; match ? match[1] : 'inspector';
}, },
dark: window.location.search.indexOf('dark') !== -1, dark: location.search.indexOf('dark') !== -1,
}; };
} }

View File

@ -5,62 +5,37 @@ import { render } from 'react-dom';
import { Container } from 'devui'; import { Container } from 'devui';
import DemoApp from './DemoApp'; import DemoApp from './DemoApp';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import reducers from './reducers'; import createRootReducer from './reducers';
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'; import { createStore, applyMiddleware, compose } from 'redux';
import logger from 'redux-logger'; import logger from 'redux-logger';
import { Router, Route, browserHistory } from 'react-router'; import { Route } from 'react-router';
import { import { createBrowserHistory } from 'history';
syncHistoryWithStore, import { ConnectedRouter, routerMiddleware } from 'connected-react-router';
routerReducer, import { persistState } from 'redux-devtools';
routerMiddleware,
} from 'react-router-redux';
import { createDevTools, persistState } from 'redux-devtools';
import DevtoolsInspector from 'redux-devtools-inspector';
import DockMonitor from 'redux-devtools-dock-monitor';
import getOptions from './getOptions'; import getOptions from './getOptions';
import TestGenerator from '../../../src'; import { ConnectedDevTools, getDevTools } from './DevTools';
function getDebugSessionKey() { function getDebugSessionKey() {
const matches = window.location.href.match(/[?&]debug_session=([^&#]+)\b/); const matches = window.location.href.match(/[?&]debug_session=([^&#]+)\b/);
return matches && matches.length > 0 ? matches[1] : null; return matches && matches.length > 0 ? matches[1] : null;
} }
const getDevTools = (options) =>
createDevTools(
<DockMonitor
defaultIsVisible
toggleVisibilityKey="ctrl-h"
changePositionKey="ctrl-q"
changeMonitorKey="ctrl-m"
>
<DevtoolsInspector
theme={options.theme}
shouldPersistState
invertTheme={!options.dark}
supportImmutable={options.supportImmutable}
tabs={(defaultTabs) => [
{
name: 'Test',
component: TestGenerator,
},
...defaultTabs,
]}
/>
</DockMonitor>
);
const ROOT = const ROOT =
process.env.NODE_ENV === 'production' ? '/redux-devtools-inspector/' : '/'; process.env.NODE_ENV === 'production'
? '/redux-devtools-test-generator/'
: '/';
let DevTools = getDevTools(getOptions()); const DevTools = getDevTools(window.location);
const reduxRouterMiddleware = routerMiddleware(browserHistory); const history = createBrowserHistory();
const useDevtoolsExtension =
!!window.__REDUX_DEVTOOLS_EXTENSION__ &&
getOptions(window.location).useExtension;
const enhancer = compose( const enhancer = compose(
applyMiddleware(logger, reduxRouterMiddleware), applyMiddleware(logger, routerMiddleware(history)),
(...args) => { (...args) => {
const useDevtoolsExtension =
!!window.__REDUX_DEVTOOLS_EXTENSION__ && getOptions().useExtension;
const instrument = useDevtoolsExtension const instrument = useDevtoolsExtension
? window.__REDUX_DEVTOOLS_EXTENSION__() ? window.__REDUX_DEVTOOLS_EXTENSION__()
: DevTools.instrument(); : DevTools.instrument();
@ -69,43 +44,20 @@ const enhancer = compose(
persistState(getDebugSessionKey()) persistState(getDebugSessionKey())
); );
const store = createStore( const store = createStore(createRootReducer(history), {}, enhancer);
combineReducers({
...reducers,
routing: routerReducer,
}),
{},
enhancer
);
const history = syncHistoryWithStore(browserHistory, store); render(
<Provider store={store}>
const handleRouterUpdate = () => { <ConnectedRouter history={history}>
renderApp(getOptions());
};
const router = (
<Router history={history} onUpdate={handleRouterUpdate}>
<Route path={ROOT} component={DemoApp} />
</Router>
);
const renderApp = (options) => {
DevTools = getDevTools(options);
const useDevtoolsExtension =
!!window.__REDUX_DEVTOOLS_EXTENSION__ && options.useExtension;
return render(
<Provider store={store}>
<Container <Container
themeData={{ theme: 'default', scheme: 'default', light: true }} themeData={{ theme: 'default', scheme: 'default', light: true }}
> >
{router} <Route path={ROOT}>
{!useDevtoolsExtension && <DevTools />} <DemoApp />
</Route>
{!useDevtoolsExtension && <ConnectedDevTools />}
</Container> </Container>
</Provider>, </ConnectedRouter>
document.getElementById('root') </Provider>,
); document.getElementById('root')
}; );
renderApp(getOptions());

View File

@ -1,5 +1,7 @@
import Immutable from 'immutable'; import Immutable from 'immutable';
import shuffle from 'lodash.shuffle'; import shuffle from 'lodash.shuffle';
import { combineReducers } from 'redux';
import { connectRouter } from 'connected-react-router';
const NESTED = { const NESTED = {
long: { long: {
@ -58,62 +60,66 @@ function createIterator() {
const DEFAULT_SHUFFLE_ARRAY = [0, 1, null, { id: 1 }, { id: 2 }, 'string']; const DEFAULT_SHUFFLE_ARRAY = [0, 1, null, { id: 1 }, { id: 2 }, 'string'];
export default { const createRootReducer = (history) =>
timeoutUpdateEnabled: (state = false, action) => combineReducers({
action.type === 'TOGGLE_TIMEOUT_UPDATE' router: connectRouter(history),
? action.timeoutUpdateEnabled timeoutUpdateEnabled: (state = false, action) =>
: state, action.type === 'TOGGLE_TIMEOUT_UPDATE'
store: (state = 0, action) => ? action.timeoutUpdateEnabled
action.type === 'INCREMENT' ? state + 1 : state, : state,
undefined: (state = { val: undefined }) => state, store: (state = 0, action) =>
null: (state = null) => state, action.type === 'INCREMENT' ? state + 1 : state,
func: (state = () => {}) => state, undefined: (state = { val: undefined }) => state,
array: (state = [], action) => null: (state = null) => state,
action.type === 'PUSH' func: (state = () => {}) => state,
? [...state, Math.random()] array: (state = [], action) =>
: action.type === 'POP' action.type === 'PUSH'
? state.slice(0, state.length - 1) ? [...state, Math.random()]
: action.type === 'REPLACE' : action.type === 'POP'
? [Math.random(), ...state.slice(1)] ? state.slice(0, state.length - 1)
: state, : action.type === 'REPLACE'
hugeArrays: (state = [], action) => ? [Math.random(), ...state.slice(1)]
action.type === 'PUSH_HUGE_ARRAY' ? [...state, ...HUGE_ARRAY] : state, : state,
hugeObjects: (state = [], action) => hugeArrays: (state = [], action) =>
action.type === 'ADD_HUGE_OBJECT' ? [...state, HUGE_OBJECT] : state, action.type === 'PUSH_HUGE_ARRAY' ? [...state, ...HUGE_ARRAY] : state,
iterators: (state = [], action) => hugeObjects: (state = [], action) =>
action.type === 'ADD_ITERATOR' ? [...state, createIterator()] : state, action.type === 'ADD_HUGE_OBJECT' ? [...state, HUGE_OBJECT] : state,
nested: (state = NESTED, action) => iterators: (state = [], action) =>
action.type === 'CHANGE_NESTED' action.type === 'ADD_ITERATOR' ? [...state, createIterator()] : state,
? { nested: (state = NESTED, action) =>
...state, action.type === 'CHANGE_NESTED'
long: { ? {
nested: [ ...state,
{ long: {
path: { nested: [
to: { {
a: state.long.nested[0].path.to.a + '!', path: {
to: {
a: state.long.nested[0].path.to.a + '!',
},
}, },
}, },
}, ],
], },
}, }
} : state,
: state, recursive: (state = [], action) =>
recursive: (state = [], action) => action.type === 'ADD_RECURSIVE' ? [...state, { ...RECURSIVE }] : state,
action.type === 'ADD_RECURSIVE' ? [...state, { ...RECURSIVE }] : state, immutables: (state = [], action) =>
immutables: (state = [], action) => action.type === 'ADD_IMMUTABLE_MAP' ? [...state, IMMUTABLE_MAP] : state,
action.type === 'ADD_IMMUTABLE_MAP' ? [...state, IMMUTABLE_MAP] : state, immutableNested: (state = IMMUTABLE_NESTED, action) =>
immutableNested: (state = IMMUTABLE_NESTED, action) => action.type === 'CHANGE_IMMUTABLE_NESTED'
action.type === 'CHANGE_IMMUTABLE_NESTED' ? state.updateIn(
? state.updateIn( ['long', 'nested', 0, 'path', 'to', 'a'],
['long', 'nested', 0, 'path', 'to', 'a'], (str) => str + '!'
(str) => str + '!' )
) : state,
: state, addFunction: (state = null, action) =>
addFunction: (state = null, action) => action.type === 'ADD_FUNCTION' ? { f: FUNC } : state,
action.type === 'ADD_FUNCTION' ? { f: FUNC } : state, addSymbol: (state = null, action) =>
addSymbol: (state = null, action) => action.type === 'ADD_SYMBOL' ? { s: window.Symbol('symbol') } : state,
action.type === 'ADD_SYMBOL' ? { s: window.Symbol('symbol') } : state, shuffleArray: (state = DEFAULT_SHUFFLE_ARRAY, action) =>
shuffleArray: (state = DEFAULT_SHUFFLE_ARRAY, action) => action.type === 'SHUFFLE_ARRAY' ? shuffle(state) : state,
action.type === 'SHUFFLE_ARRAY' ? shuffle(state) : state, });
};
export default createRootReducer;

View File

@ -44,15 +44,18 @@
"@babel/preset-react": "^7.10.4", "@babel/preset-react": "^7.10.4",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0", "clean-webpack-plugin": "^3.0.0",
"connected-react-router": "^6.8.0",
"css-loader": "^4.2.1", "css-loader": "^4.2.1",
"enzyme": "^3.11.0", "enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.3", "enzyme-adapter-react-16": "^1.15.3",
"enzyme-to-json": "^3.5.0", "enzyme-to-json": "^3.5.0",
"expect": "^26.2.0", "expect": "^26.2.0",
"file-loader": "^6.0.0", "file-loader": "^6.0.0",
"history": "^4.10.1",
"html-webpack-plugin": "^4.3.0", "html-webpack-plugin": "^4.3.0",
"immutable": "^4.0.0-rc.12", "immutable": "^4.0.0-rc.12",
"jest": "^26.2.2", "jest": "^26.2.2",
"lodash.isequalwith": "^4.4.0",
"lodash.shuffle": "^4.2.0", "lodash.shuffle": "^4.2.0",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-redux": "^7.2.1", "react-redux": "^7.2.1",
@ -64,6 +67,7 @@
"redux-devtools-inspector": "^0.13.0", "redux-devtools-inspector": "^0.13.0",
"redux-logger": "^3.0.6", "redux-logger": "^3.0.6",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"seamless-immutable": "^7.1.4",
"style-loader": "^1.2.1", "style-loader": "^1.2.1",
"webpack": "^4.44.1", "webpack": "^4.44.1",
"webpack-dev-server": "^3.11.0" "webpack-dev-server": "^3.11.0"