use recursive partial so we don't have to use "as"

This commit is contained in:
David Lechner
2021-01-22 10:35:11 -06:00
parent e1932febb2
commit caacaad341
4 changed files with 19 additions and 22 deletions
+5 -11
View File
@@ -35,8 +35,6 @@ import {
} from '../actions/lwp3-bootloader';
import { didCompile } from '../actions/mpy';
import { HubType, Result } from '../protocols/lwp3-bootloader';
import { EditorState } from '../reducers/editor';
import { SettingsState } from '../reducers/settings';
import { createCountFunc } from '../utils/iter';
import flashFirmware from './flash-firmware';
@@ -69,7 +67,7 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, { nextMessageId: createCountFunc() });
saga.setState({ settings: { flashCurrentProgram: false } as SettingsState });
saga.setState({ settings: { flashCurrentProgram: false } });
// saga is triggered by this action
@@ -199,9 +197,7 @@ describe('flashFirmware', () => {
nextMessageId: createCountFunc(),
});
saga.setState({
settings: { flashCurrentProgram: false } as SettingsState,
});
saga.setState({ settings: { flashCurrentProgram: false } });
// saga is triggered by this action
@@ -332,9 +328,7 @@ describe('flashFirmware', () => {
nextMessageId: createCountFunc(),
});
saga.setState({
settings: { flashCurrentProgram: false } as SettingsState,
});
saga.setState({ settings: { flashCurrentProgram: false } });
// saga is triggered by this action
@@ -387,8 +381,8 @@ describe('flashFirmware', () => {
const saga = new AsyncSaga(flashFirmware, { nextMessageId: createCountFunc() });
saga.setState({
editor: { current: editor } as EditorState,
settings: { flashCurrentProgram: true } as SettingsState,
editor: { current: editor },
settings: { flashCurrentProgram: true },
});
// saga is triggered by this action
+4 -4
View File
@@ -6,7 +6,7 @@
import { AsyncSaga, delay } from '../../test';
import { openLicenseDialog } from '../actions/app';
import { didFailToFetchList, didFetchList } from '../actions/license';
import { LicenseList, LicenseState } from '../reducers/license';
import { LicenseList } from '../reducers/license';
import license from './license';
afterAll(() => {
@@ -24,7 +24,7 @@ describe('fetchLicenses', () => {
// initially, license list starts as null, so fetch is called to get
// the list
saga.setState({ license: { list: null } as LicenseState });
saga.setState({ license: { list: null } });
saga.put(openLicenseDialog());
const action = await saga.take();
@@ -42,7 +42,7 @@ describe('fetchLicenses', () => {
// after we have the list, we don't fetch it again since it will
// always be the same list
saga.setState({ license: { list: testLicenseList } as LicenseState });
saga.setState({ license: { list: testLicenseList } });
saga.put(openLicenseDialog());
// have to yield to be sure fetch call would have taken place on error
@@ -56,7 +56,7 @@ describe('fetchLicenses', () => {
jest.spyOn(globalThis, 'fetch').mockResolvedValue(failResponse);
saga.setState({ license: { list: null } as LicenseState });
saga.setState({ license: { list: null } });
saga.put(openLicenseDialog());
const action = await saga.take();
+4 -5
View File
@@ -6,7 +6,6 @@
import { AsyncSaga } from '../../test';
import { didStart } from '../actions/app';
import { didBooleanChange, didFailToSetBoolean, setBoolean } from '../actions/settings';
import { SettingsState } from '../reducers/settings';
import { SettingId } from '../settings/user';
import settings from './settings';
@@ -221,7 +220,7 @@ describe('store settings to local storage', () => {
throw testError;
});
saga.setState({ settings: { showDocs: false } as SettingsState });
saga.setState({ settings: { showDocs: false } });
saga.put(setBoolean(SettingId.ShowDocs, true));
expect(mockSetItem).toHaveBeenCalled();
@@ -246,7 +245,7 @@ describe('store settings to local storage', () => {
expect(value).toBe('true');
});
saga.setState({ settings: { showDocs: false } as SettingsState });
saga.setState({ settings: { showDocs: false } });
saga.put(setBoolean(SettingId.ShowDocs, true));
expect(mockSetItem).toHaveBeenCalled();
@@ -266,7 +265,7 @@ describe('store settings to local storage', () => {
expect(value).toBe('false');
});
saga.setState({ settings: { darkMode: true } as SettingsState });
saga.setState({ settings: { darkMode: true } });
saga.put(setBoolean(SettingId.DarkMode, false));
expect(mockSetItem).toHaveBeenCalled();
@@ -286,7 +285,7 @@ describe('store settings to local storage', () => {
expect(value).toBe('false');
});
saga.setState({ settings: { flashCurrentProgram: true } as SettingsState });
saga.setState({ settings: { flashCurrentProgram: true } });
saga.put(setBoolean(SettingId.FlashCurrentProgram, false));
expect(mockSetItem).toHaveBeenCalled();
+6 -2
View File
@@ -5,11 +5,15 @@ import { END, MulticastChannel, Saga, Task, runSaga, stdChannel } from 'redux-sa
import { Action } from '../src/actions';
import { RootState } from '../src/reducers';
type RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>;
};
export class AsyncSaga {
private channel: MulticastChannel<Action>;
private dispatches: (Action | END)[];
private takers: { put: (action: Action | END) => void }[];
private state: Partial<RootState>;
private state: RecursivePartial<RootState>;
private task: Task;
public constructor(saga: Saga, context?: Record<string, unknown>) {
@@ -63,7 +67,7 @@ export class AsyncSaga {
return Promise.resolve(next);
}
public setState(state: Partial<RootState>): void {
public setState(state: RecursivePartial<RootState>): void {
this.state = state;
}