From 1d6d3867d2cdab772a026cac695cf0651d3bbe50 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Sat, 12 Sep 2020 19:56:00 -0400 Subject: [PATCH] compiles --- packages/devui/src/Dialog/Dialog.tsx | 4 +- .../src/index.ts | 1 + .../src/TestGenerator.tsx | 73 +++++++++---------- .../src/es6template.ts | 6 ++ .../src/index.tsx | 16 ++-- .../src/redux/ava/index.ts | 11 ++- .../src/redux/jest/index.ts | 12 +-- .../src/redux/mocha/index.ts | 12 +-- .../src/redux/tape/index.ts | 11 ++- .../src/simple-diff.ts | 64 ++++++++++++++++ .../src/templateForm.ts | 14 ++-- .../src/types.ts | 19 ++++- .../src/vanilla/ava/index.ts | 16 ++-- .../src/vanilla/jest/index.ts | 16 ++-- .../src/vanilla/mocha/index.ts | 23 ++++-- .../src/vanilla/tape/index.ts | 16 ++-- 16 files changed, 214 insertions(+), 100 deletions(-) create mode 100644 packages/redux-devtools-test-generator/src/es6template.ts create mode 100644 packages/redux-devtools-test-generator/src/simple-diff.ts diff --git a/packages/devui/src/Dialog/Dialog.tsx b/packages/devui/src/Dialog/Dialog.tsx index dc058b4e..6ae80aa9 100644 --- a/packages/devui/src/Dialog/Dialog.tsx +++ b/packages/devui/src/Dialog/Dialog.tsx @@ -44,13 +44,13 @@ function isForm

(rest?: FormProps

): rest is FormProps

{ } export default class Dialog

extends (PureComponent || Component)< - DialogProps | (DialogProps & FormProps

) + DialogProps | (Omit & FormProps

) > { submitButton?: HTMLInputElement | null; onSubmit = () => { if (this.submitButton) this.submitButton.click(); - else this.props.onSubmit(); + else (this.props.onSubmit as () => void)(); }; getFormButtonRef: React.RefCallback = (node) => { diff --git a/packages/redux-devtools-inspector-monitor/src/index.ts b/packages/redux-devtools-inspector-monitor/src/index.ts index 3d52c0e0..01eb309d 100644 --- a/packages/redux-devtools-inspector-monitor/src/index.ts +++ b/packages/redux-devtools-inspector-monitor/src/index.ts @@ -1,3 +1,4 @@ import DevtoolsInspector from './DevtoolsInspector'; export default DevtoolsInspector; export { TabComponentProps } from './ActionPreview'; +export { DevtoolsInspectorState } from './redux'; diff --git a/packages/redux-devtools-test-generator/src/TestGenerator.tsx b/packages/redux-devtools-test-generator/src/TestGenerator.tsx index c4a8e319..e2c85934 100644 --- a/packages/redux-devtools-test-generator/src/TestGenerator.tsx +++ b/packages/redux-devtools-test-generator/src/TestGenerator.tsx @@ -3,38 +3,49 @@ import PropTypes from 'prop-types'; import { stringify } from 'javascript-stringify'; import objectPath from 'object-path'; import jsan from 'jsan'; -import diff from 'simple-diff'; +import diff, { Event } from 'simple-diff'; import es6template from 'es6template'; import { Editor } from 'devui'; import { TabComponentProps } from 'redux-devtools-inspector-monitor'; import { Action } from 'redux'; +import { AssertionLocals, DispatcherLocals, WrapLocals } from './types'; -export const fromPath = (path) => +export const fromPath = (path: (string | number)[]) => path.map((a) => (typeof a === 'string' ? `.${a}` : `[${a}]`)).join(''); -function getState(s, defaultValue) { +// eslint-disable-next-line @typescript-eslint/ban-types +function getState(s: { state: S; error?: string }, defaultValue: {}) { if (!s) return defaultValue; return JSON.parse(jsan.stringify(s.state)); } -export function compare(s1: S, s2: S, cb, defaultValue) { - const paths = []; // Already processed - function generate({ type, newPath, newValue, newIndex }) { - let curState; - let path = fromPath(newPath); +export function compare( + s1: { state: S; error?: string }, + s2: { state: S; error?: string }, + cb: (value: { path: string; curState: number | string | undefined }) => void, + // eslint-disable-next-line @typescript-eslint/ban-types + defaultValue: {} +) { + const paths: string[] = []; // Already processed + function generate( + event: Event | { type: 'move-item'; newPath: (string | number)[] } + ) { + let curState: number | string | undefined; + let path = fromPath(event.newPath); - if (type === 'remove-item' || type === 'move-item') { + if (event.type === 'remove-item' || event.type === 'move-item') { if (paths.length && paths.indexOf(path) !== -1) return; paths.push(path); - const v = objectPath.get(s2.state, newPath); + // eslint-disable-next-line @typescript-eslint/ban-types + const v = objectPath.get((s2.state as unknown) as object, event.newPath); curState = v.length; path += '.length'; - } else if (type === 'add-item') { - generate({ type: 'move-item', newPath }); - path += `[${newIndex}]`; - curState = stringify(newValue); + } else if (event.type === 'add-item') { + generate({ type: 'move-item', newPath: event.newPath }); + path += `[${event.newIndex}]`; + curState = stringify(event.newValue); } else { - curState = stringify(newValue); + curState = stringify(event.newValue); } // console.log(`expect(store${path}).toEqual(${curState});`); @@ -51,9 +62,9 @@ interface Props> extends Omit, 'monitorState' | 'updateMonitorState'> { name?: string; isVanilla?: boolean; - wrap?: unknown; - dispatcher?: unknown; - assertion?: unknown; + wrap?: string | ((locals: WrapLocals) => string); + dispatcher?: string | ((locals: DispatcherLocals) => string); + assertion?: string | ((locals: AssertionLocals) => string); useCodemirror: boolean; indentation?: number; header?: ReactNode; @@ -118,9 +129,12 @@ export default class TestGenerator< curState, }: { path: string; - curState: string | undefined; + curState: number | string | undefined; }) => { - r += `${space}${assertion({ path, curState })}\n`; + r += `${space}${(assertion as (locals: AssertionLocals) => string)({ + path, + curState, + })}\n`; }; while (actions[i]) { @@ -133,7 +147,7 @@ export default class TestGenerator< else r += space; if (!isVanilla || (actions[i].action.type as string)[0] !== '@') { r += - dispatcher({ + (dispatcher as (locals: DispatcherLocals) => string)({ action: !isVanilla ? this.getAction(actions[i].action) : this.getMethod(actions[i].action), @@ -164,7 +178,7 @@ export default class TestGenerator< if (!isVanilla) r = wrap({ name, assertions: r }); else { r = wrap({ - name: /^[a-zA-Z0-9_-]+?$/.test(name) ? name : 'Store', + name: /^[a-zA-Z0-9_-]+?$/.test(name as string) ? name : 'Store', actionName: (selectedActionId === null || selectedActionId > 0) && actions[startIdx] @@ -196,21 +210,6 @@ export default class TestGenerator< return ; } - static propTypes = { - name: PropTypes.string, - isVanilla: PropTypes.bool, - computedStates: PropTypes.array, - actions: PropTypes.object, - selectedActionId: PropTypes.number, - startActionId: PropTypes.number, - wrap: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), - dispatcher: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), - assertion: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), - useCodemirror: PropTypes.bool, - indentation: PropTypes.number, - header: PropTypes.element, - }; - static defaultProps = { useCodemirror: true, selectedActionId: null, diff --git a/packages/redux-devtools-test-generator/src/es6template.ts b/packages/redux-devtools-test-generator/src/es6template.ts new file mode 100644 index 00000000..9828d0ef --- /dev/null +++ b/packages/redux-devtools-test-generator/src/es6template.ts @@ -0,0 +1,6 @@ +declare module 'es6template' { + const _default: { + compile(template: string): (locals: Locals) => string; + }; + export default _default; +} diff --git a/packages/redux-devtools-test-generator/src/index.tsx b/packages/redux-devtools-test-generator/src/index.tsx index e7c34b57..011946df 100644 --- a/packages/redux-devtools-test-generator/src/index.tsx +++ b/packages/redux-devtools-test-generator/src/index.tsx @@ -11,7 +11,10 @@ import { import { MdAdd } from 'react-icons/md'; import { MdEdit } from 'react-icons/md'; import { Action } from 'redux'; -import { TabComponentProps } from 'redux-devtools-inspector-monitor'; +import { + DevtoolsInspectorState, + TabComponentProps, +} from 'redux-devtools-inspector-monitor'; import { formSchema, uiSchema, defaultFormData } from './templateForm'; import TestGenerator from './TestGenerator'; import jestTemplate from './redux/jest/template'; @@ -19,7 +22,6 @@ import mochaTemplate from './redux/mocha/template'; import tapeTemplate from './redux/tape/template'; import avaTemplate from './redux/ava/template'; import { Template } from './types'; -import { DevtoolsInspectorState } from 'redux-devtools-inspector-monitor/lib/redux'; export const getDefaultTemplates = (/* lib */): Template[] => /* @@ -33,7 +35,7 @@ export const getDefaultTemplates = (/* lib */): Template[] => interface TestGeneratorMonitorState { hideTip?: boolean; selected?: number; - templates: Template[]; + templates?: Template[]; } interface State { @@ -63,7 +65,7 @@ export default class TestTab> extends Component< this.setState({ dialogStatus: null }); }; - handleSubmit = ({ formData: template }) => { + handleSubmit = ({ formData: template }: { formData: Template }) => { const { templates = getDefaultTemplates(), selected = 0, @@ -106,7 +108,7 @@ export default class TestTab> extends Component< this.setState({ dialogStatus: 'Edit' }); }; - updateState = (newState) => { + updateState = (newState: TestGeneratorMonitorState) => { this.props.updateMonitorState({ testGenerator: { ...(this.props.monitorState as { @@ -146,7 +148,7 @@ export default class TestTab> extends Component< {!assertion ? ( No template for tests specified. ) : ( - isVanilla={false} assertion={assertion} dispatcher={dispatcher} @@ -160,7 +162,7 @@ export default class TestTab> extends Component< )} {dialogStatus && ( -

open title={`${dialogStatus} test template`} onDismiss={this.handleCloseDialog} diff --git a/packages/redux-devtools-test-generator/src/redux/ava/index.ts b/packages/redux-devtools-test-generator/src/redux/ava/index.ts index d0b8e97d..960e8e9d 100644 --- a/packages/redux-devtools-test-generator/src/redux/ava/index.ts +++ b/packages/redux-devtools-test-generator/src/redux/ava/index.ts @@ -1,11 +1,14 @@ +import { AssertionLocals, DispatcherLocals, WrapLocals } from '../../types'; + export const name = 'Ava template'; -export const dispatcher = ({ action, prevState }) => - `state = reducers(${prevState}, ${action});`; +export const dispatcher = ({ action, prevState }: DispatcherLocals) => + `state = reducers(${prevState!}, ${action!});`; -export const assertion = ({ curState }) => `t.deepEqual(state, ${curState});`; +export const assertion = ({ curState }: AssertionLocals) => + `t.deepEqual(state, ${curState!});`; -export const wrap = ({ assertions }) => +export const wrap = ({ assertions }: WrapLocals) => `import test from 'ava'; import reducers from '../../reducers'; diff --git a/packages/redux-devtools-test-generator/src/redux/jest/index.ts b/packages/redux-devtools-test-generator/src/redux/jest/index.ts index 8c4b625a..379eb3fb 100644 --- a/packages/redux-devtools-test-generator/src/redux/jest/index.ts +++ b/packages/redux-devtools-test-generator/src/redux/jest/index.ts @@ -1,12 +1,14 @@ +import { AssertionLocals, DispatcherLocals, WrapLocals } from '../../types'; + export const name = 'Jest template'; -export const dispatcher = ({ action, prevState }) => - `state = reducers(${prevState}, ${action});`; +export const dispatcher = ({ action, prevState }: DispatcherLocals) => + `state = reducers(${prevState!}, ${action!});`; -export const assertion = ({ curState }) => - `expect(state).toEqual(${curState});`; +export const assertion = ({ curState }: AssertionLocals) => + `expect(state).toEqual(${curState!});`; -export const wrap = ({ assertions }) => +export const wrap = ({ assertions }: WrapLocals) => `import reducers from '../../reducers'; test('reducers', () => { diff --git a/packages/redux-devtools-test-generator/src/redux/mocha/index.ts b/packages/redux-devtools-test-generator/src/redux/mocha/index.ts index e1df405e..b8c944aa 100644 --- a/packages/redux-devtools-test-generator/src/redux/mocha/index.ts +++ b/packages/redux-devtools-test-generator/src/redux/mocha/index.ts @@ -1,12 +1,14 @@ +import { AssertionLocals, DispatcherLocals, WrapLocals } from '../../types'; + export const name = 'Mocha template'; -export const dispatcher = ({ action, prevState }) => - `state = reducers(${prevState}, ${action});`; +export const dispatcher = ({ action, prevState }: DispatcherLocals) => + `state = reducers(${prevState!}, ${action!});`; -export const assertion = ({ curState }) => - `expect(state).toEqual(${curState});`; +export const assertion = ({ curState }: AssertionLocals) => + `expect(state).toEqual(${curState!});`; -export const wrap = ({ assertions }) => +export const wrap = ({ assertions }: WrapLocals) => `import expect from 'expect'; import reducers from '../../reducers'; diff --git a/packages/redux-devtools-test-generator/src/redux/tape/index.ts b/packages/redux-devtools-test-generator/src/redux/tape/index.ts index 037ce601..5a8a843a 100644 --- a/packages/redux-devtools-test-generator/src/redux/tape/index.ts +++ b/packages/redux-devtools-test-generator/src/redux/tape/index.ts @@ -1,11 +1,14 @@ +import { AssertionLocals, DispatcherLocals, WrapLocals } from '../../types'; + export const name = 'Tape template'; -export const dispatcher = ({ action, prevState }) => - `state = reducers(${prevState}, ${action});`; +export const dispatcher = ({ action, prevState }: DispatcherLocals) => + `state = reducers(${prevState!}, ${action!});`; -export const assertion = ({ curState }) => `t.deepEqual(state, ${curState});`; +export const assertion = ({ curState }: AssertionLocals) => + `t.deepEqual(state, ${curState!});`; -export const wrap = ({ assertions }) => +export const wrap = ({ assertions }: WrapLocals) => `import test from 'tape'; import reducers from '../../reducers'; diff --git a/packages/redux-devtools-test-generator/src/simple-diff.ts b/packages/redux-devtools-test-generator/src/simple-diff.ts new file mode 100644 index 00000000..e5fcafff --- /dev/null +++ b/packages/redux-devtools-test-generator/src/simple-diff.ts @@ -0,0 +1,64 @@ +declare module 'simple-diff' { + interface AddEvent { + oldPath: (string | number)[]; + newPath: (string | number)[]; + type: 'add'; + oldValue: undefined; + newValue: unknown; + } + + interface RemoveEvent { + oldPath: (string | number)[]; + newPath: (string | number)[]; + type: 'remove'; + oldValue: unknown; + newValue: undefined; + } + + interface ChangeEvent { + oldPath: (string | number)[]; + newPath: (string | number)[]; + type: 'change'; + oldValue: unknown; + newValue: unknown; + } + + interface AddItemEvent { + oldPath: (string | number)[]; + newPath: (string | number)[]; + type: 'add-item'; + oldIndex: -1; + curIndex: -1; + newIndex: number; + newValue: unknown; + } + + interface RemoveItemEvent { + oldPath: (string | number)[]; + newPath: (string | number)[]; + type: 'remove-item'; + oldIndex: number; + curIndex: number; + newIndex: -1; + oldValue: unknown; + } + + interface MoveItemEvent { + oldPath: (string | number)[]; + newPath: (string | number)[]; + type: 'move-item'; + oldIndex: number; + curIndex: number; + newIndex: number; + } + + export type Event = + | AddEvent + | RemoveEvent + | ChangeEvent + | AddItemEvent + | RemoveItemEvent + | MoveItemEvent; + + export default function (oldObj: unknown, newObj: unknown): Event[]; +} diff --git a/packages/redux-devtools-test-generator/src/templateForm.ts b/packages/redux-devtools-test-generator/src/templateForm.ts index b496a2d5..217c6008 100644 --- a/packages/redux-devtools-test-generator/src/templateForm.ts +++ b/packages/redux-devtools-test-generator/src/templateForm.ts @@ -1,21 +1,23 @@ +import { Template } from './types'; + export const formSchema = { - type: 'object', + type: 'object' as const, required: ['name'], properties: { name: { - type: 'string', + type: 'string' as const, title: 'Template name', }, dispatcher: { - type: 'string', + type: 'string' as const, title: 'Dispatcher: ({ action, prevState }) => (`