clipper/frontend/src/HudCanvasState.test.ts

295 lines
8.5 KiB
TypeScript

import {
stateReducer,
SelectionMode,
EmptySelectionAction,
HoverState,
} from './HudCanvasState';
const initialState = {
width: 5000,
emptySelectionAction: EmptySelectionAction.SelectNothing,
hoverX: 0,
selection: { x1: 0, x2: 0 },
origSelection: { x1: 0, x2: 0 },
mousedownX: 0,
mode: SelectionMode.Normal,
prevMode: SelectionMode.Normal,
cursorClass: 'cursor-auto',
hoverState: HoverState.Normal,
shouldPublish: false,
};
describe('stateReducer', () => {
describe('setselection', () => {
it('sets the selection', () => {
const state = stateReducer(
{ ...initialState },
{ type: 'setselection', x: 0, selection: { x1: 100, x2: 200 } }
);
expect(state.selection).toEqual({ x1: 100, x2: 200 });
expect(state.shouldPublish).toBeFalsy();
});
});
describe.each([
{
name: 'entering resizing start',
x: 995,
selection: { x1: 1000, x2: 2000 },
wantMode: SelectionMode.ResizingStart,
wantSelection: { x1: 1000, x2: 2000 },
},
{
name: 'entering resizing end',
x: 2003,
selection: { x1: 1000, x2: 2000 },
wantMode: SelectionMode.ResizingEnd,
wantSelection: { x1: 1000, x2: 2000 },
},
{
name: 'entering dragging',
x: 1500,
selection: { x1: 1000, x2: 2000 },
wantMode: SelectionMode.Dragging,
wantSelection: { x1: 1000, x2: 2000 },
},
{
name: 'entering selecting',
x: 10,
selection: { x1: 1000, x2: 2000 },
wantMode: SelectionMode.Selecting,
wantSelection: { x1: 10, x2: 10 },
},
])('mousedown', ({ name, x, selection, wantMode, wantSelection }) => {
test(`${name} generates the expected state`, () => {
const state = stateReducer(
{ ...initialState, selection: selection },
{ type: 'mousedown', x: x }
);
expect(state.mode).toEqual(wantMode);
expect(state.selection).toEqual(wantSelection);
expect(state.mousedownX).toEqual(x);
expect(state.shouldPublish).toBeTruthy();
});
});
describe.each([
{
name: 're-entering normal mode',
x: 1200,
selection: { x1: 1000, x2: 2000 },
emptySelectionAction: EmptySelectionAction.SelectNothing,
wantSelection: { x1: 1000, x2: 2000 },
},
{
name: 'when nothing is selected and emptySelectionAction is SelectNothing',
x: 1200,
selection: { x1: 1000, x2: 1000 },
emptySelectionAction: EmptySelectionAction.SelectNothing,
wantSelection: { x1: 1200, x2: 1200 },
},
{
// TODO: broken
name: 'when nothing is selected and emptySelectionAction is SelectPrevious',
x: 1200,
selection: { x1: 1000, x2: 2000 },
emptySelectionAction: EmptySelectionAction.SelectPrevious,
wantSelection: { x1: 1000, x2: 2000 },
},
])(
'mouseup',
({ name, x, selection, emptySelectionAction, wantSelection }) => {
test(`${name} generates the expected state`, () => {
const state = stateReducer(
{
...initialState,
selection: selection,
mode: SelectionMode.Selecting,
emptySelectionAction: emptySelectionAction,
},
{ type: 'mouseup', x: x }
);
expect(state.mode).toEqual(SelectionMode.Normal);
expect(state.prevMode).toEqual(SelectionMode.Selecting);
expect(state.selection).toEqual(wantSelection);
expect(state.shouldPublish).toBeTruthy();
});
}
);
describe('mouseleave', () => {
it('sets the state', () => {
const state = stateReducer(
{
...initialState,
selection: { x1: 2000, x2: 3000 },
mode: SelectionMode.Dragging,
mousedownX: 475,
},
{ type: 'mouseleave', x: 500 }
);
expect(state.mode).toEqual(SelectionMode.Dragging);
expect(state.selection).toEqual({ x1: 2000, x2: 3000 });
expect(state.mousedownX).toEqual(475);
expect(state.hoverX).toEqual(0);
expect(state.shouldPublish).toBeFalsy();
});
});
describe('mousemove', () => {
describe.each([
// Normal mode
{
name: 'hovering over selection start',
mode: SelectionMode.Normal,
x: 997,
selection: { x1: 1000, x2: 3000 },
wantHoverState: HoverState.OverSelectionStart,
shouldPublish: false,
},
{
name: 'hovering over selection end',
mode: SelectionMode.Normal,
x: 3009,
selection: { x1: 1000, x2: 3000 },
wantHoverState: HoverState.OverSelectionEnd,
shouldPublish: false,
},
{
name: 'hovering over selection',
mode: SelectionMode.Normal,
x: 1200,
selection: { x1: 1000, x2: 3000 },
wantHoverState: HoverState.OverSelection,
shouldPublish: false,
},
{
name: 'hovering elsewhere',
mode: SelectionMode.Normal,
x: 300,
selection: { x1: 1000, x2: 3000 },
wantHoverState: HoverState.Normal,
shouldPublish: false,
},
// Selecting mode
{
name: 'when not crossing over',
mode: SelectionMode.Selecting,
x: 3005,
mousedownX: 2000,
selection: { x1: 2000, x2: 3000 },
wantSelection: { x1: 2000, x2: 3005 },
shouldPublish: true,
},
{
name: 'when crossing over',
mode: SelectionMode.Selecting,
x: 1995,
mousedownX: 2000,
selection: { x1: 2000, x2: 2002 },
wantSelection: { x1: 1995, x2: 2000 },
shouldPublish: true,
},
// Dragging mode
{
name: 'in the middle of the canvas',
mode: SelectionMode.Dragging,
x: 1220,
mousedownX: 1200,
selection: { x1: 1000, x2: 1500 },
origSelection: { x1: 1000, x2: 1500 },
wantSelection: { x1: 1020, x2: 1520 },
shouldPublish: true,
},
{
name: 'at the start of the canvas',
mode: SelectionMode.Dragging,
x: 30,
mousedownX: 50,
selection: { x1: 10, x2: 210 },
origSelection: { x1: 10, x2: 210 },
wantSelection: { x1: 0, x2: 200 },
shouldPublish: true,
},
{
name: 'at the end of the canvas',
mode: SelectionMode.Dragging,
x: 1400,
mousedownX: 1250,
selection: { x1: 4800, x2: 4900 },
origSelection: { x1: 4800, x2: 4900 },
wantSelection: { x1: 4900, x2: 5000 },
shouldPublish: true,
},
// ResizingStart mode
{
name: 'when not crossing over',
mode: SelectionMode.ResizingStart,
x: 2020,
selection: { x1: 2000, x2: 3000 },
origSelection: { x1: 2000, x2: 3000 },
wantSelection: { x1: 2020, x2: 3000 },
shouldPublish: true,
},
{
name: 'when crossing over',
mode: SelectionMode.ResizingStart,
x: 2010,
selection: { x1: 2000, x2: 2002 },
origSelection: { x1: 2000, x2: 2002 },
wantSelection: { x1: 2002, x2: 2010 },
shouldPublish: true,
},
// ResizingEnd mode
{
name: 'when not crossing over',
mode: SelectionMode.ResizingEnd,
x: 2007,
selection: { x1: 1000, x2: 2000 },
origSelection: { x1: 1000, x2: 2000 },
wantSelection: { x1: 1000, x2: 2007 },
shouldPublish: true,
},
{
name: 'when crossing over',
mode: SelectionMode.ResizingEnd,
x: 1995,
selection: { x1: 2000, x2: 2002 },
origSelection: { x1: 2000, x2: 2002 },
wantSelection: { x1: 1995, x2: 2000 },
shouldPublish: true,
},
])(
'mousemove',
({
name,
mode,
x,
mousedownX = 0,
selection,
origSelection = { x1: 0, x2: 0 },
wantSelection = selection,
wantHoverState = HoverState.Normal,
shouldPublish,
}) => {
test(`${SelectionMode[mode]} mode: ${name} generates the expected state`, () => {
const state = stateReducer(
{
...initialState,
selection: selection,
origSelection: origSelection,
mode: mode,
mousedownX: mousedownX,
},
{ type: 'mousemove', x: x }
);
expect(state.mode).toEqual(mode);
expect(state.selection).toEqual(wantSelection);
expect(state.hoverState).toEqual(wantHoverState);
expect(state.shouldPublish).toEqual(shouldPublish);
});
}
);
});
});