Skip to content

Commit

Permalink
Test PendingEditContext
Browse files Browse the repository at this point in the history
  • Loading branch information
jdeniau committed Apr 18, 2024
1 parent 5fa3b5e commit 87176b1
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 45 deletions.
45 changes: 45 additions & 0 deletions src/contexts/PendingEditContext.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { describe, expect, test } from 'vitest';
import { PendingEdit, PendingEditState } from '../sql/types';
import { testables } from './PendingEditContext';

const { reducer, ActionType } = testables;

const edit: PendingEdit = {
state: PendingEditState.Pending,
connectionSlug: 'conn',
tableName: 'tablename',
primaryKeys: { id: 123 },
values: { title: 'new title' },
};

const edit2: PendingEdit = {
state: PendingEditState.Pending,
connectionSlug: 'conn',
tableName: 'tablename',
primaryKeys: { id: 123 },
values: { status: 'new status' },
};

describe('reducer', () => {
test('addPendingEdit', () => {
let newState = reducer([], {
type: ActionType.Add,
edit,
});

expect(newState).toEqual([edit]);

newState = reducer(newState, { type: ActionType.Add, edit: edit2 });

expect(newState).toEqual([edit, edit2]);
});

test('markAllAsApplied', () => {
expect(
reducer([edit, edit2], { type: ActionType.MarkAllAsApplied })
).toEqual([
{ ...edit, state: PendingEditState.Applied },
{ ...edit2, state: PendingEditState.Applied },
]);
});
});
48 changes: 16 additions & 32 deletions src/contexts/PendingEditContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
useMemo,
useReducer,
} from 'react';
import { Button } from 'antd';
import { FieldPacket, RowDataPacket } from 'mysql2';
import invariant from 'tiny-invariant';
import { PendingEdit, PendingEditState } from '../sql/types';
Expand All @@ -29,13 +28,20 @@ const PendingEditContext = createContext<PendingEditContextType | null>(null);

type State = Array<PendingEdit>;

type Action = { type: 'add'; edit: PendingEdit } | { type: 'markAllAsApplied' };
enum ActionType {
Add = 'add',
MarkAllAsApplied = 'MarkAllAsApplied',
}

type Action =
| { type: ActionType.Add; edit: PendingEdit }
| { type: ActionType.MarkAllAsApplied };

function reducer(state: State, action: Action): State {
switch (action.type) {
case 'add':
case ActionType.Add:
return [...state, action.edit];
case 'markAllAsApplied':
case ActionType.MarkAllAsApplied:
return state.map((edit) => ({
...edit,
state: PendingEditState.Applied,
Expand All @@ -58,7 +64,7 @@ export function PendingEditContextProvider({
invariant(currentConnectionSlug, 'Current connection slug should be set');

dispatch({
type: 'add',
type: ActionType.Add,
edit: {
state: PendingEditState.Pending,
connectionSlug: currentConnectionSlug,
Expand All @@ -70,7 +76,7 @@ export function PendingEditContextProvider({
);

const markAllAsApplied = useCallback(
() => dispatch({ type: 'markAllAsApplied' }),
() => dispatch({ type: ActionType.MarkAllAsApplied }),
[]
);

Expand Down Expand Up @@ -134,29 +140,7 @@ export function usePendingEditContext() {

return context;
}
export function PendingEditDebug() {
const { pendingEdits, markAllAsApplied } = usePendingEditContext();

const unappliedPendingEdits = pendingEdits.filter(
(edit) => edit.state === PendingEditState.Pending
);

return (
<Button
title="Synchronize"
danger={unappliedPendingEdits.length > 0}
onClick={() => {
window.sql.handlePendingEdits(pendingEdits).then((r) => {
console.log(r);

// Mark all as applied
markAllAsApplied();
});
// alert(JSON.stringify(pendingEdits, null, 2));
}}
>
🔃
{unappliedPendingEdits.length}
</Button>
);
}
export const testables = {
reducer,
ActionType,
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Select } from 'antd';
import { LOCALE_LIST } from '../../configuration/locale';
import { useConfiguration } from '../../contexts/ConfigurationContext';
import { LOCALE_LIST } from '../../../configuration/locale';
import { useConfiguration } from '../../../contexts/ConfigurationContext';

export default function LangSelector() {
const { configuration, changeLanguage } = useConfiguration();
Expand Down
30 changes: 30 additions & 0 deletions src/renderer/component/Layout/PendingEditSyncButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Button } from 'antd';
import { usePendingEditContext } from '../../../contexts/PendingEditContext';
import { PendingEditState } from '../../../sql/types';

export function PendingEditSyncButton() {
const { pendingEdits, markAllAsApplied } = usePendingEditContext();

const unappliedPendingEdits = pendingEdits.filter(
(edit) => edit.state === PendingEditState.Pending
);

return (
<Button
title="Synchronize"
danger={unappliedPendingEdits.length > 0}
onClick={() => {
window.sql.handlePendingEdits(pendingEdits).then((r) => {
console.log(r);

// Mark all as applied
markAllAsApplied();
});
// alert(JSON.stringify(pendingEdits, null, 2));
}}
>
🔃
{unappliedPendingEdits.length}
</Button>
);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Select } from 'antd';
import { THEME_LIST } from '../../configuration/themes';
import { useTheme } from '../../contexts/ThemeContext';
import { background, selection } from '../theme';
import { THEME_LIST } from '../../../configuration/themes';
import { useTheme } from '../../../contexts/ThemeContext';
import { background, selection } from '../../theme';

export default function ThemeSelector() {
const { themeName, changeTheme } = useTheme();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function RawSqlResult({ fetcher }: Props) {
{result && isRowDataPacketArray(result[0]) && (
// TOOD maybe fetch foreign keys of queried table to activate navlinks
<TableGrid
editable // TODO need propers primary keys to really b editable
editable // TODO need propers primary keys to really be editable
result={result[0]}
fields={result[1]}
title={() => t('rawSql.result.title')}
Expand Down
12 changes: 5 additions & 7 deletions src/renderer/routes/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,17 @@ import packageJson from '../../../package.json';
import { ConfigurationContextProvider } from '../../contexts/ConfigurationContext';
import { useConnectionContext } from '../../contexts/ConnectionContext';
import { useDatabaseContext } from '../../contexts/DatabaseContext';
import {
PendingEditContextProvider,
PendingEditDebug,
} from '../../contexts/PendingEditContext';
import { PendingEditContextProvider } from '../../contexts/PendingEditContext';
import { ThemeContextProvider } from '../../contexts/ThemeContext';
import { useTranslation } from '../../i18n';
import ButtonLink from '../component/ButtonLink';
import ConnectionStack from '../component/Connection/ConnectionStack';
import ConnectionNav from '../component/Connection/Nav';
import Debug from '../component/Debug';
import { KeyboardShortcutTooltip } from '../component/KeyboardShortcut';
import LangSelector from '../component/LangSelector';
import ThemeSelector from '../component/ThemeSelector';
import LangSelector from '../component/Layout/LangSelector';
import { PendingEditSyncButton } from '../component/Layout/PendingEditSyncButton';
import ThemeSelector from '../component/Layout/ThemeSelector';
import useEffectOnce from '../hooks/useEffectOnce';
import { background, foreground, selection } from '../theme';

Expand Down Expand Up @@ -95,7 +93,7 @@ export default function Root() {
<ConnectionNav />

<Flex gap="small" align="center">
<PendingEditDebug />
<PendingEditSyncButton />
{t('language.switch.label')} <LangSelector />
{t('theme.switch.label')} <ThemeSelector />
</Flex>
Expand Down

0 comments on commit 87176b1

Please sign in to comment.