Refactor HudCanvasState tests

This commit is contained in:
Rob Watson 2022-02-03 19:44:28 +01:00
parent 6ba19b3e01
commit a855d589f3
1 changed files with 220 additions and 320 deletions

View File

@ -31,110 +31,91 @@ describe('stateReducer', () => {
}); });
}); });
describe('mousedown', () => { describe.each([
describe('when hovering over the selection start', () => { {
it('updates the state', () => { name: 'entering resizing start',
const state = stateReducer( x: 995,
{ ...initialState, selection: { start: 1000, end: 2000 } }, selection: { start: 1000, end: 2000 },
{ type: 'mousedown', x: 995 } wantMode: SelectionMode.ResizingStart,
); wantSelection: { start: 1000, end: 2000 },
expect(state.mode).toEqual(SelectionMode.ResizingStart); },
expect(state.selection).toEqual({ start: 1000, end: 2000 }); {
expect(state.mousedownX).toEqual(995); name: 'entering resizing end',
expect(state.shouldPublish).toBeTruthy(); x: 2003,
}); selection: { start: 1000, end: 2000 },
}); wantMode: SelectionMode.ResizingEnd,
describe('when hovering over the selection end', () => { wantSelection: { start: 1000, end: 2000 },
it('updates the state', () => { },
const state = stateReducer( {
{ ...initialState, selection: { start: 1000, end: 2000 } }, name: 'entering dragging',
{ type: 'mousedown', x: 2003 } x: 1500,
); selection: { start: 1000, end: 2000 },
expect(state.mode).toEqual(SelectionMode.ResizingEnd); wantMode: SelectionMode.Dragging,
expect(state.selection).toEqual({ start: 1000, end: 2000 }); wantSelection: { start: 1000, end: 2000 },
expect(state.mousedownX).toEqual(2003); },
expect(state.shouldPublish).toBeTruthy(); {
}); name: 'entering selecting',
}); x: 10,
describe('when hovering over the selection', () => { selection: { start: 1000, end: 2000 },
it('updates the state', () => { wantMode: SelectionMode.Selecting,
const state = stateReducer( wantSelection: { start: 10, end: 10 },
{ ...initialState, selection: { start: 1000, end: 2000 } }, },
{ type: 'mousedown', x: 1500 } ])('mousedown', ({ name, x, selection, wantMode, wantSelection }) => {
); test(`${name} generates the expected state`, () => {
expect(state.mode).toEqual(SelectionMode.Dragging); const state = stateReducer(
expect(state.selection).toEqual({ start: 1000, end: 2000 }); { ...initialState, selection: selection },
expect(state.mousedownX).toEqual(1500); { type: 'mousedown', x: x }
expect(state.shouldPublish).toBeTruthy(); );
}); expect(state.mode).toEqual(wantMode);
}); expect(state.selection).toEqual(wantSelection);
describe('when not hovering over the selection', () => { expect(state.mousedownX).toEqual(x);
it('updates the state', () => { expect(state.shouldPublish).toBeTruthy();
const state = stateReducer(
{ ...initialState, selection: { start: 1000, end: 2000 } },
{ type: 'mousedown', x: 3000 }
);
expect(state.mode).toEqual(SelectionMode.Selecting);
expect(state.selection).toEqual({ start: 3000, end: 3000 });
expect(state.mousedownX).toEqual(3000);
expect(state.shouldPublish).toBeTruthy();
});
}); });
}); });
describe('mouseup', () => { describe.each([
describe('when re-entering normal mode', () => { {
it('updates the state', () => { name: 're-entering normal mode',
x: 1200,
selection: { start: 1000, end: 2000 },
emptySelectionAction: EmptySelectionAction.SelectNothing,
wantSelection: { start: 1000, end: 2000 },
},
{
name: 'when nothing is selected and emptySelectionAction is SelectNothing',
x: 1200,
selection: { start: 1000, end: 1000 },
emptySelectionAction: EmptySelectionAction.SelectNothing,
wantSelection: { start: 1200, end: 1200 },
},
{
// TODO: broken
name: 'when nothing is selected and emptySelectionAction is SelectPrevious',
x: 1200,
selection: { start: 1000, end: 2000 },
emptySelectionAction: EmptySelectionAction.SelectPrevious,
wantSelection: { start: 1000, end: 2000 },
},
])(
'mouseup',
({ name, x, selection, emptySelectionAction, wantSelection }) => {
test(`${name} generates the expected state`, () => {
const state = stateReducer( const state = stateReducer(
{ {
...initialState, ...initialState,
selection: { start: 1000, end: 2000 }, selection: selection,
mode: SelectionMode.Selecting, mode: SelectionMode.Selecting,
mousedownX: 1200, emptySelectionAction: emptySelectionAction,
}, },
{ type: 'mouseup', x: 0 } { type: 'mouseup', x: x }
); );
expect(state.mode).toEqual(SelectionMode.Normal); expect(state.mode).toEqual(SelectionMode.Normal);
expect(state.selection).toEqual({ start: 1000, end: 2000 }); expect(state.prevMode).toEqual(SelectionMode.Selecting);
expect(state.mousedownX).toEqual(1200); expect(state.selection).toEqual(wantSelection);
expect(state.shouldPublish).toBeTruthy(); expect(state.shouldPublish).toBeTruthy();
}); });
}); }
);
describe('nothing is selected and emptySelectionAction is SelectNothing', () => {
it('clears the selection at the mouse x coord', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 1000, end: 1000 },
mode: SelectionMode.Selecting,
emptySelectionAction: EmptySelectionAction.SelectNothing,
},
{ type: 'mouseup', x: 500 }
);
expect(state.mode).toEqual(SelectionMode.Normal);
expect(state.selection).toEqual({ start: 500, end: 500 });
expect(state.shouldPublish).toBeTruthy();
});
});
describe('nothing is selected and emptySelectionAction is SelectPrevious', () => {
it('reverts to the previous selection', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 1000, end: 2000 },
mode: SelectionMode.Selecting,
emptySelectionAction: EmptySelectionAction.SelectNothing,
},
{ type: 'mouseup', x: 0 }
);
expect(state.mode).toEqual(SelectionMode.Normal);
expect(state.selection).toEqual({ start: 1000, end: 2000 });
expect(state.shouldPublish).toBeTruthy();
});
});
});
describe('mouseleave', () => { describe('mouseleave', () => {
it('sets the state', () => { it('sets the state', () => {
@ -155,239 +136,158 @@ describe('stateReducer', () => {
}); });
describe('mousemove', () => { describe('mousemove', () => {
describe('in normal mode', () => { describe.each([
describe('when hovering over the selection start', () => { // Normal mode
it('updates the state', () => { {
name: 'hovering over selection start',
mode: SelectionMode.Normal,
x: 997,
selection: { start: 1000, end: 3000 },
wantHoverState: HoverState.OverSelectionStart,
shouldPublish: false,
},
{
name: 'hovering over selection end',
mode: SelectionMode.Normal,
x: 3009,
selection: { start: 1000, end: 3000 },
wantHoverState: HoverState.OverSelectionEnd,
shouldPublish: false,
},
{
name: 'hovering over selection',
mode: SelectionMode.Normal,
x: 1200,
selection: { start: 1000, end: 3000 },
wantHoverState: HoverState.OverSelection,
shouldPublish: false,
},
{
name: 'hovering elsewhere',
mode: SelectionMode.Normal,
x: 300,
selection: { start: 1000, end: 3000 },
wantHoverState: HoverState.Normal,
shouldPublish: false,
},
// Selecting mode
{
name: 'when not crossing over',
mode: SelectionMode.Selecting,
x: 3005,
mousedownX: 2000,
selection: { start: 2000, end: 3000 },
wantSelection: { start: 2000, end: 3005 },
shouldPublish: true,
},
{
name: 'when crossing over',
mode: SelectionMode.Selecting,
x: 1995,
mousedownX: 2000,
selection: { start: 2000, end: 2002 },
wantSelection: { start: 1995, end: 2000 },
shouldPublish: true,
},
// Dragging mode
{
name: 'in the middle of the canvas',
mode: SelectionMode.Dragging,
x: 1220,
mousedownX: 1200,
selection: { start: 1000, end: 1500 },
origSelection: { start: 1000, end: 1500 },
wantSelection: { start: 1020, end: 1520 },
shouldPublish: true,
},
{
name: 'at the start of the canvas',
mode: SelectionMode.Dragging,
x: 30,
mousedownX: 50,
selection: { start: 10, end: 210 },
origSelection: { start: 10, end: 210 },
wantSelection: { start: 0, end: 200 },
shouldPublish: true,
},
{
name: 'at the end of the canvas',
mode: SelectionMode.Dragging,
x: 1400,
mousedownX: 1250,
selection: { start: 4800, end: 4900 },
origSelection: { start: 4800, end: 4900 },
wantSelection: { start: 4900, end: 5000 },
shouldPublish: true,
},
// ResizingStart mode
{
name: 'when not crossing over',
mode: SelectionMode.ResizingStart,
x: 2020,
selection: { start: 2000, end: 3000 },
origSelection: { start: 2000, end: 3000 },
wantSelection: { start: 2020, end: 3000 },
shouldPublish: true,
},
{
name: 'when crossing over',
mode: SelectionMode.ResizingStart,
x: 2010,
selection: { start: 2000, end: 2002 },
origSelection: { start: 2000, end: 2002 },
wantSelection: { start: 2002, end: 2010 },
shouldPublish: true,
},
// ResizingEnd mode
{
name: 'when not crossing over',
mode: SelectionMode.ResizingEnd,
x: 2007,
selection: { start: 1000, end: 2000 },
origSelection: { start: 1000, end: 2000 },
wantSelection: { start: 1000, end: 2007 },
shouldPublish: true,
},
{
name: 'when crossing over',
mode: SelectionMode.ResizingEnd,
x: 1995,
selection: { start: 2000, end: 2002 },
origSelection: { start: 2000, end: 2002 },
wantSelection: { start: 1995, end: 2000 },
shouldPublish: true,
},
])(
'mousemove',
({
name,
mode,
x,
mousedownX = 0,
selection,
origSelection = { start: 0, end: 0 },
wantSelection = selection,
wantHoverState = HoverState.Normal,
shouldPublish,
}) => {
test(`${SelectionMode[mode]} mode: ${name} generates the expected state`, () => {
const state = stateReducer( const state = stateReducer(
{ {
...initialState, ...initialState,
selection: { start: 1000, end: 3000 }, selection: selection,
mode: SelectionMode.Normal, origSelection: origSelection,
mode: mode,
mousedownX: mousedownX,
}, },
{ type: 'mousemove', x: 997 } { type: 'mousemove', x: x }
); );
expect(state.mode).toEqual(SelectionMode.Normal); expect(state.mode).toEqual(mode);
expect(state.selection).toEqual({ start: 1000, end: 3000 }); expect(state.selection).toEqual(wantSelection);
expect(state.hoverState).toEqual(HoverState.OverSelectionStart); expect(state.hoverState).toEqual(wantHoverState);
expect(state.shouldPublish).toBeFalsy(); expect(state.shouldPublish).toEqual(shouldPublish);
}); });
}); }
);
describe('when hovering over the selection end', () => {
it('updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 1000, end: 3000 },
mode: SelectionMode.Normal,
},
{ type: 'mousemove', x: 3009 }
);
expect(state.mode).toEqual(SelectionMode.Normal);
expect(state.selection).toEqual({ start: 1000, end: 3000 });
expect(state.hoverState).toEqual(HoverState.OverSelectionEnd);
expect(state.shouldPublish).toBeFalsy();
});
});
describe('when hovering over the selection', () => {
it('updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 1000, end: 3000 },
mode: SelectionMode.Normal,
},
{ type: 'mousemove', x: 1200 }
);
expect(state.mode).toEqual(SelectionMode.Normal);
expect(state.selection).toEqual({ start: 1000, end: 3000 });
expect(state.hoverState).toEqual(HoverState.OverSelection);
expect(state.shouldPublish).toBeFalsy();
});
});
describe('when hovering elsewhere', () => {
it('updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 1000, end: 3000 },
mode: SelectionMode.Normal,
},
{ type: 'mousemove', x: 10 }
);
expect(state.mode).toEqual(SelectionMode.Normal);
expect(state.selection).toEqual({ start: 1000, end: 3000 });
expect(state.hoverState).toEqual(HoverState.Normal);
expect(state.shouldPublish).toBeFalsy();
});
});
});
describe('in selecting mode', () => {
describe('a normal selection', () => {
it('updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 2000, end: 3000 },
mode: SelectionMode.Selecting,
mousedownX: 2000,
},
{ type: 'mousemove', x: 3005 }
);
expect(state.mode).toEqual(SelectionMode.Selecting);
expect(state.selection).toEqual({ start: 2000, end: 3005 });
expect(state.shouldPublish).toBeTruthy();
});
});
describe('when crossing over', () => {
it('updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 2000, end: 2002 },
mode: SelectionMode.Selecting,
mousedownX: 2000,
},
{ type: 'mousemove', x: 1995 }
);
expect(state.mode).toEqual(SelectionMode.Selecting);
expect(state.selection).toEqual({ start: 1995, end: 2000 });
expect(state.shouldPublish).toBeTruthy();
});
});
});
describe('in dragging mode', () => {
describe('in the middle of the canvas', () => {
it('updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 1000, end: 1500 },
origSelection: { start: 1000, end: 1500 },
mode: SelectionMode.Dragging,
mousedownX: 1200,
},
{ type: 'mousemove', x: 1220 }
);
expect(state.mode).toEqual(SelectionMode.Dragging);
expect(state.selection).toEqual({ start: 1020, end: 1520 });
expect(state.shouldPublish).toBeTruthy();
});
});
describe('at the start of the canvas', () => {
it('constrains the movement and updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 10, end: 210 },
origSelection: { start: 10, end: 210 },
mode: SelectionMode.Dragging,
mousedownX: 50,
},
{ type: 'mousemove', x: 30 }
);
expect(state.mode).toEqual(SelectionMode.Dragging);
expect(state.selection).toEqual({ start: 0, end: 200 });
expect(state.shouldPublish).toBeTruthy();
});
});
describe('at the end of the canvas', () => {
it('constrains the movement and updates the state', () => {
const state = stateReducer(
{
...initialState,
width: 3000,
selection: { start: 2800, end: 2900 },
origSelection: { start: 2800, end: 2900 },
mode: SelectionMode.Dragging,
mousedownX: 1200,
},
{ type: 'mousemove', x: 1350 }
);
expect(state.mode).toEqual(SelectionMode.Dragging);
expect(state.selection).toEqual({ start: 2900, end: 3000 });
expect(state.shouldPublish).toBeTruthy();
});
});
});
describe('in resizing start mode', () => {
describe('a normal resize', () => {
it('updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 2000, end: 3000 },
origSelection: { start: 2000, end: 3000 },
mode: SelectionMode.ResizingStart,
},
{ type: 'mousemove', x: 2020 }
);
expect(state.mode).toEqual(SelectionMode.ResizingStart);
expect(state.selection).toEqual({ start: 2020, end: 3000 });
expect(state.shouldPublish).toBeTruthy();
});
});
describe('when crossing over', () => {
it('updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 2000, end: 2002 },
origSelection: { start: 2000, end: 2002 },
mode: SelectionMode.ResizingStart,
},
{ type: 'mousemove', x: 2010 }
);
expect(state.mode).toEqual(SelectionMode.ResizingStart);
expect(state.selection).toEqual({ start: 2002, end: 2010 });
expect(state.shouldPublish).toBeTruthy();
});
});
});
describe('in resizing end mode', () => {
describe('a normal resize', () => {
it('updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 1000, end: 2000 },
origSelection: { start: 1000, end: 2000 },
mode: SelectionMode.ResizingEnd,
},
{ type: 'mousemove', x: 2007 }
);
expect(state.mode).toEqual(SelectionMode.ResizingEnd);
expect(state.selection).toEqual({ start: 1000, end: 2007 });
expect(state.shouldPublish).toBeTruthy();
});
});
describe('when crossing over', () => {
it('updates the state', () => {
const state = stateReducer(
{
...initialState,
selection: { start: 2000, end: 2002 },
origSelection: { start: 2000, end: 2002 },
mode: SelectionMode.ResizingEnd,
},
{ type: 'mousemove', x: 1995 }
);
expect(state.mode).toEqual(SelectionMode.ResizingEnd);
expect(state.selection).toEqual({ start: 1995, end: 2000 });
expect(state.shouldPublish).toBeTruthy();
});
});
});
}); });
}); });