Merge pull request #74 from tldraw/test/commands
test(commands): add coverage for when commands shouldn't run
This commit is contained in:
commit
5c37979969
16 changed files with 312 additions and 161 deletions
|
@ -5,69 +5,73 @@ import { AlignType } from '~types'
|
|||
describe('Align command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
tlstate.align(AlignType.Top)
|
||||
describe('when less than two shapes are selected', () => {
|
||||
it('does nothing', () => {
|
||||
tlstate.loadDocument(mockDocument).select('rect2')
|
||||
const initialState = tlstate.state
|
||||
tlstate.align(AlignType.Top)
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(tlstate.getShape('rect2').point).toEqual([100, 0])
|
||||
|
||||
tlstate.undo()
|
||||
|
||||
expect(tlstate.getShape('rect2').point).toEqual([100, 100])
|
||||
|
||||
tlstate.redo()
|
||||
|
||||
expect(tlstate.getShape('rect2').point).toEqual([100, 0])
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('aligns top', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
tlstate.align(AlignType.Top)
|
||||
describe('when multiple shapes are selected', () => {
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
})
|
||||
|
||||
expect(tlstate.getShape('rect2').point).toEqual([100, 0])
|
||||
})
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.align(AlignType.Top)
|
||||
|
||||
it('aligns right', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
tlstate.align(AlignType.Right)
|
||||
expect(tlstate.getShape('rect2').point).toEqual([100, 0])
|
||||
|
||||
expect(tlstate.getShape('rect1').point).toEqual([100, 0])
|
||||
})
|
||||
tlstate.undo()
|
||||
|
||||
it('aligns bottom', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
tlstate.align(AlignType.Bottom)
|
||||
expect(tlstate.getShape('rect2').point).toEqual([100, 100])
|
||||
|
||||
expect(tlstate.getShape('rect1').point).toEqual([0, 100])
|
||||
})
|
||||
tlstate.redo()
|
||||
|
||||
it('aligns left', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
tlstate.align(AlignType.Left)
|
||||
expect(tlstate.getShape('rect2').point).toEqual([100, 0])
|
||||
})
|
||||
|
||||
expect(tlstate.getShape('rect2').point).toEqual([0, 100])
|
||||
})
|
||||
it('aligns top', () => {
|
||||
tlstate.align(AlignType.Top)
|
||||
|
||||
it('aligns center horizontal', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
tlstate.align(AlignType.CenterHorizontal)
|
||||
expect(tlstate.getShape('rect2').point).toEqual([100, 0])
|
||||
})
|
||||
|
||||
expect(tlstate.getShape('rect1').point).toEqual([50, 0])
|
||||
expect(tlstate.getShape('rect2').point).toEqual([50, 100])
|
||||
})
|
||||
it('aligns right', () => {
|
||||
tlstate.align(AlignType.Right)
|
||||
|
||||
it('aligns center vertical', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
tlstate.align(AlignType.CenterVertical)
|
||||
expect(tlstate.getShape('rect1').point).toEqual([100, 0])
|
||||
})
|
||||
|
||||
expect(tlstate.getShape('rect1').point).toEqual([0, 50])
|
||||
expect(tlstate.getShape('rect2').point).toEqual([100, 50])
|
||||
it('aligns bottom', () => {
|
||||
tlstate.align(AlignType.Bottom)
|
||||
|
||||
expect(tlstate.getShape('rect1').point).toEqual([0, 100])
|
||||
})
|
||||
|
||||
it('aligns left', () => {
|
||||
tlstate.align(AlignType.Left)
|
||||
|
||||
expect(tlstate.getShape('rect2').point).toEqual([0, 100])
|
||||
})
|
||||
|
||||
it('aligns center horizontal', () => {
|
||||
tlstate.align(AlignType.CenterHorizontal)
|
||||
|
||||
expect(tlstate.getShape('rect1').point).toEqual([50, 0])
|
||||
expect(tlstate.getShape('rect2').point).toEqual([50, 100])
|
||||
})
|
||||
|
||||
it('aligns center vertical', () => {
|
||||
tlstate.align(AlignType.CenterVertical)
|
||||
|
||||
expect(tlstate.getShape('rect1').point).toEqual([0, 50])
|
||||
expect(tlstate.getShape('rect2').point).toEqual([100, 50])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -4,8 +4,22 @@ import { mockDocument } from '~test'
|
|||
describe('Create command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when no shape is provided', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.create()
|
||||
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
const shape = { ...tlstate.getShape('rect1'), id: 'rect4' }
|
||||
tlstate.create(shape)
|
||||
|
||||
|
|
|
@ -4,9 +4,22 @@ import { mockDocument } from '~test'
|
|||
describe('Delete page', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when there are no pages in the current document', () => {
|
||||
it('does nothing', () => {
|
||||
tlstate.resetDocument()
|
||||
const initialState = tlstate.state
|
||||
tlstate.deletePage('page1')
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
const initialId = tlstate.currentPageId
|
||||
|
||||
tlstate.createPage()
|
||||
|
|
|
@ -6,8 +6,21 @@ import type { TLDrawShape } from '~types'
|
|||
describe('Delete command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when no shape is selected', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.delete()
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.select('rect2')
|
||||
tlstate.delete()
|
||||
|
||||
|
@ -26,7 +39,6 @@ describe('Delete command', () => {
|
|||
})
|
||||
|
||||
it('deletes two shapes', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
tlstate.delete()
|
||||
|
||||
|
@ -45,8 +57,6 @@ describe('Delete command', () => {
|
|||
})
|
||||
|
||||
it('deletes bound shapes', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
|
||||
expect(Object.values(tlstate.page.bindings)[0]).toBe(undefined)
|
||||
|
||||
tlstate
|
||||
|
@ -86,26 +96,18 @@ describe('Delete command', () => {
|
|||
expect(tlstate.getShape('arrow1').handles?.start.bindingId).toBe(undefined)
|
||||
})
|
||||
|
||||
describe('when deleting grouped shapes', () => {
|
||||
describe('when deleting shapes in a group', () => {
|
||||
it('updates the group', () => {
|
||||
tlstate
|
||||
.loadDocument(mockDocument)
|
||||
.group(['rect1', 'rect2', 'rect3'], 'newGroup')
|
||||
.select('rect1')
|
||||
.delete()
|
||||
tlstate.group(['rect1', 'rect2', 'rect3'], 'newGroup').select('rect1').delete()
|
||||
|
||||
expect(tlstate.getShape('rect1')).toBeUndefined()
|
||||
expect(tlstate.getShape('newGroup').children).toStrictEqual(['rect2', 'rect3'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('when deleting shapes with children', () => {
|
||||
it('also deletes the children', () => {
|
||||
tlstate
|
||||
.loadDocument(mockDocument)
|
||||
.group(['rect1', 'rect2'], 'newGroup')
|
||||
.select('newGroup')
|
||||
.delete()
|
||||
describe('when deleting a group', () => {
|
||||
it('deletes all grouped shapes', () => {
|
||||
tlstate.group(['rect1', 'rect2'], 'newGroup').select('newGroup').delete()
|
||||
|
||||
expect(tlstate.getShape('rect1')).toBeUndefined()
|
||||
expect(tlstate.getShape('rect2')).toBeUndefined()
|
||||
|
|
|
@ -4,11 +4,26 @@ import { DistributeType } from '~types'
|
|||
|
||||
describe('Distribute command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when less than three shapes are selected', () => {
|
||||
it('does nothing', () => {
|
||||
tlstate.select('rect1', 'rect2')
|
||||
const initialState = tlstate.state
|
||||
tlstate.distribute(DistributeType.Horizontal)
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.selectAll()
|
||||
tlstate.distribute(DistributeType.Horizontal)
|
||||
|
||||
expect(tlstate.getShape('rect3').point).toEqual([50, 20])
|
||||
tlstate.undo()
|
||||
expect(tlstate.getShape('rect3').point).toEqual([20, 20])
|
||||
|
@ -17,9 +32,9 @@ describe('Distribute command', () => {
|
|||
})
|
||||
|
||||
it('distributes vertically', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
tlstate.distribute(DistributeType.Vertical)
|
||||
|
||||
expect(tlstate.getShape('rect3').point).toEqual([20, 50])
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,14 +1,28 @@
|
|||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import { TLDrawState } from '~state'
|
||||
import { mockDocument } from '~test'
|
||||
import { ArrowShape, GroupShape, TLDrawShapeType } from '~types'
|
||||
import { ArrowShape, TLDrawShapeType } from '~types'
|
||||
|
||||
describe('Duplicate command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.select('rect1')
|
||||
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when no shape is selected', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.duplicate()
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.select('rect1')
|
||||
|
||||
expect(Object.keys(tlstate.getPage().shapes).length).toBe(3)
|
||||
|
||||
tlstate.duplicate()
|
||||
|
@ -121,7 +135,6 @@ describe('Duplicate command', () => {
|
|||
})
|
||||
|
||||
it('duplicates groups', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.group(['rect1', 'rect2'], 'newGroup').select('newGroup')
|
||||
|
||||
const beforeShapeIds = Object.keys(tlstate.page.shapes)
|
||||
|
@ -140,7 +153,6 @@ describe('Duplicate command', () => {
|
|||
})
|
||||
|
||||
it('duplicates grouped shapes', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.group(['rect1', 'rect2'], 'newGroup').select('rect1')
|
||||
|
||||
const beforeShapeIds = Object.keys(tlstate.page.shapes)
|
||||
|
|
|
@ -5,8 +5,21 @@ import type { RectangleShape } from '~types'
|
|||
describe('Flip command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when no shape is selected', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.flipHorizontal()
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.select('rect1', 'rect2')
|
||||
tlstate.flipHorizontal()
|
||||
|
||||
|
@ -22,7 +35,6 @@ describe('Flip command', () => {
|
|||
})
|
||||
|
||||
it('flips horizontally', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.select('rect1', 'rect2')
|
||||
tlstate.flipHorizontal()
|
||||
|
||||
|
@ -30,7 +42,6 @@ describe('Flip command', () => {
|
|||
})
|
||||
|
||||
it('flips vertically', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.select('rect1', 'rect2')
|
||||
tlstate.flipVertical()
|
||||
|
||||
|
|
|
@ -6,8 +6,11 @@ import { GroupShape, TLDrawShape, TLDrawShapeType } from '~types'
|
|||
describe('Group command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.group(['rect1', 'rect2'], 'newGroup')
|
||||
|
||||
expect(tlstate.getShape<GroupShape>('newGroup')).toBeTruthy()
|
||||
|
@ -23,7 +26,6 @@ describe('Group command', () => {
|
|||
|
||||
describe('when less than two shapes are selected', () => {
|
||||
it('does nothing', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.deselectAll()
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -49,8 +51,6 @@ describe('Group command', () => {
|
|||
*/
|
||||
|
||||
it('creates a group with the correct props', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
|
||||
tlstate.updateShapes(
|
||||
{
|
||||
id: 'rect1',
|
||||
|
@ -74,8 +74,6 @@ describe('Group command', () => {
|
|||
})
|
||||
|
||||
it('reparents the grouped shapes', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
|
||||
tlstate.updateShapes(
|
||||
{
|
||||
id: 'rect1',
|
||||
|
@ -114,9 +112,9 @@ describe('Group command', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('when grouping shapes that are the child of another group', () => {
|
||||
describe('when grouping shapes that already belong to a group', () => {
|
||||
/*
|
||||
Do not allow groups to nest. All groups should be the parent of
|
||||
Do not allow groups to nest. All groups should be children of
|
||||
the page: a group should never be the child of a different group.
|
||||
This is a UX decision as much as a technical one.
|
||||
*/
|
||||
|
@ -125,7 +123,8 @@ describe('Group command', () => {
|
|||
/*
|
||||
When the selected shapes are the children of another group, and so
|
||||
long as the children do not represent ALL of the group's children,
|
||||
then a new group should be created that is a child of the parent group.
|
||||
then a new group should be created from the selected shapes and the
|
||||
original group be updated to only contain the remaining ones.
|
||||
*/
|
||||
|
||||
tlstate.resetDocument().createShapes(
|
||||
|
@ -206,7 +205,7 @@ describe('Group command', () => {
|
|||
expect(tlstate.getShape<GroupShape>('newGroupB').children).toStrictEqual(['rect1', 'rect3'])
|
||||
})
|
||||
|
||||
it('does not group shapes if shapes are all the groups children', () => {
|
||||
it('does nothing if all shapes in the group are selected', () => {
|
||||
/*
|
||||
If the selected shapes represent ALL of the children of the a
|
||||
group, then no effect should occur.
|
||||
|
@ -269,7 +268,7 @@ describe('Group command', () => {
|
|||
])
|
||||
})
|
||||
|
||||
it('marges selected groups that no longer have children', () => {
|
||||
it('merges selected groups that no longer have children', () => {
|
||||
/*
|
||||
If the user is creating a group while having selected other
|
||||
groups, then the selected groups should be destroyed and a new
|
||||
|
|
|
@ -5,9 +5,23 @@ import { ArrowShape, TLDrawShapeType } from '~types'
|
|||
describe('Move to page command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument).createPage('page2').changePage('page1')
|
||||
})
|
||||
|
||||
describe('when no shape is selected', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.moveToPage('page2')
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
Moving shapes to a new page should remove those shapes from the
|
||||
current page and add them to the specifed page. If bindings exist
|
||||
current page and add them to the specified page. If bindings exist
|
||||
that effect the moved shapes, then the bindings should be destroyed
|
||||
on the old page and created on the new page only if both the "to"
|
||||
and "from" shapes were moved. The app should then change pages to
|
||||
|
@ -15,12 +29,7 @@ describe('Move to page command', () => {
|
|||
*/
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate
|
||||
.loadDocument(mockDocument)
|
||||
.createPage('page2')
|
||||
.changePage('page1')
|
||||
.select('rect1', 'rect2')
|
||||
.moveToPage('page2')
|
||||
tlstate.select('rect1', 'rect2').moveToPage('page2')
|
||||
|
||||
expect(tlstate.currentPageId).toBe('page2')
|
||||
expect(tlstate.getShape('rect1', 'page1')).toBeUndefined()
|
||||
|
@ -51,7 +60,6 @@ describe('Move to page command', () => {
|
|||
describe('when moving shapes with bindings', () => {
|
||||
it('deletes bindings when only the bound-to shape is moved', () => {
|
||||
tlstate
|
||||
.loadDocument(mockDocument)
|
||||
.selectAll()
|
||||
.delete()
|
||||
.createShapes(
|
||||
|
@ -66,7 +74,7 @@ describe('Move to page command', () => {
|
|||
const bindingId = tlstate.bindings[0].id
|
||||
expect(tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId).toBe(bindingId)
|
||||
|
||||
tlstate.createPage('page2').changePage('page1').select('target1').moveToPage('page2')
|
||||
tlstate.select('target1').moveToPage('page2')
|
||||
|
||||
expect(
|
||||
tlstate.getShape<ArrowShape>('arrow1', 'page1').handles.start.bindingId
|
||||
|
@ -93,7 +101,6 @@ describe('Move to page command', () => {
|
|||
|
||||
it('deletes bindings when only the bound-from shape is moved', () => {
|
||||
tlstate
|
||||
.loadDocument(mockDocument)
|
||||
.selectAll()
|
||||
.delete()
|
||||
.createShapes(
|
||||
|
@ -108,7 +115,7 @@ describe('Move to page command', () => {
|
|||
const bindingId = tlstate.bindings[0].id
|
||||
expect(tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId).toBe(bindingId)
|
||||
|
||||
tlstate.createPage('page2').changePage('page1').select('arrow1').moveToPage('page2')
|
||||
tlstate.select('arrow1').moveToPage('page2')
|
||||
|
||||
expect(
|
||||
tlstate.getShape<ArrowShape>('arrow1', 'page2').handles.start.bindingId
|
||||
|
@ -135,7 +142,6 @@ describe('Move to page command', () => {
|
|||
|
||||
it('moves bindings when both shapes are moved', () => {
|
||||
tlstate
|
||||
.loadDocument(mockDocument)
|
||||
.selectAll()
|
||||
.delete()
|
||||
.createShapes(
|
||||
|
@ -150,11 +156,7 @@ describe('Move to page command', () => {
|
|||
const bindingId = tlstate.bindings[0].id
|
||||
expect(tlstate.getShape<ArrowShape>('arrow1').handles.start.bindingId).toBe(bindingId)
|
||||
|
||||
tlstate
|
||||
.createPage('page2')
|
||||
.changePage('page1')
|
||||
.select('arrow1', 'target1')
|
||||
.moveToPage('page2')
|
||||
tlstate.select('arrow1', 'target1').moveToPage('page2')
|
||||
|
||||
expect(tlstate.getShape<ArrowShape>('arrow1', 'page2').handles.start.bindingId).toBe(
|
||||
bindingId
|
||||
|
@ -182,12 +184,7 @@ describe('Move to page command', () => {
|
|||
|
||||
describe('when moving grouped shapes', () => {
|
||||
it('moves groups and their children', () => {
|
||||
tlstate
|
||||
.loadDocument(mockDocument)
|
||||
.createPage('page2')
|
||||
.changePage('page1')
|
||||
.group(['rect1', 'rect2'], 'groupA')
|
||||
.moveToPage('page2')
|
||||
tlstate.group(['rect1', 'rect2'], 'groupA').moveToPage('page2')
|
||||
|
||||
expect(tlstate.getShape('rect1', 'page1')).toBeUndefined()
|
||||
expect(tlstate.getShape('rect2', 'page1')).toBeUndefined()
|
||||
|
@ -218,18 +215,10 @@ describe('Move to page command', () => {
|
|||
expect(tlstate.getShape('groupA', 'page2')).toBeDefined()
|
||||
})
|
||||
|
||||
it('deletes groups shapes if the groups children were all moved', () => {
|
||||
// ...
|
||||
})
|
||||
it.todo('deletes groups shapes if the groups children were all moved')
|
||||
|
||||
it('reparents grouped shapes if the group is not moved', () => {
|
||||
tlstate
|
||||
.loadDocument(mockDocument)
|
||||
.createPage('page2')
|
||||
.changePage('page1')
|
||||
.group(['rect1', 'rect2', 'rect3'], 'groupA')
|
||||
.select('rect1')
|
||||
.moveToPage('page2')
|
||||
tlstate.group(['rect1', 'rect2', 'rect3'], 'groupA').select('rect1').moveToPage('page2')
|
||||
|
||||
expect(tlstate.getShape('rect1', 'page1')).toBeUndefined()
|
||||
expect(tlstate.getShape('rect1', 'page2')).toBeDefined()
|
||||
|
|
|
@ -42,8 +42,22 @@ function getSortedIndices(data: Data) {
|
|||
}
|
||||
|
||||
describe('Move command', () => {
|
||||
it('does, undoes and redoes command', () => {
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(doc)
|
||||
})
|
||||
|
||||
describe('when no shape is selected', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.moveToBack()
|
||||
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.select('b')
|
||||
tlstate.moveToBack()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('bacd')
|
||||
|
@ -55,7 +69,6 @@ describe('Move command', () => {
|
|||
|
||||
describe('to back', () => {
|
||||
it('moves a shape to back', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('b')
|
||||
tlstate.moveToBack()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('bacd')
|
||||
|
@ -63,7 +76,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves two adjacent siblings to back', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('b', 'c')
|
||||
tlstate.moveToBack()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('bcad')
|
||||
|
@ -71,7 +83,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves two non-adjacent siblings to back', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('b', 'd')
|
||||
tlstate.moveToBack()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('bdac')
|
||||
|
@ -81,7 +92,6 @@ describe('Move command', () => {
|
|||
|
||||
describe('backward', () => {
|
||||
it('moves a shape backward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('c')
|
||||
tlstate.moveBackward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('acbd')
|
||||
|
@ -89,7 +99,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves a shape at first index backward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('a')
|
||||
tlstate.moveBackward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||
|
@ -97,7 +106,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves two adjacent siblings backward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('c', 'd')
|
||||
tlstate.moveBackward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('acdb')
|
||||
|
@ -105,7 +113,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves two non-adjacent siblings backward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('b', 'd')
|
||||
tlstate.moveBackward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('badc')
|
||||
|
@ -113,7 +120,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves two adjacent siblings backward at zero index', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('a', 'b')
|
||||
tlstate.moveBackward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||
|
@ -123,7 +129,6 @@ describe('Move command', () => {
|
|||
|
||||
describe('forward', () => {
|
||||
it('moves a shape forward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('c')
|
||||
tlstate.moveForward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('abdc')
|
||||
|
@ -131,7 +136,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves a shape forward at the top index', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('b')
|
||||
tlstate.moveForward()
|
||||
tlstate.moveForward()
|
||||
|
@ -141,7 +145,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves two adjacent siblings forward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('a', 'b')
|
||||
tlstate.moveForward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('cabd')
|
||||
|
@ -149,7 +152,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves two non-adjacent siblings forward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('a', 'c')
|
||||
tlstate.moveForward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('badc')
|
||||
|
@ -157,7 +159,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves two adjacent siblings forward at top index', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('c', 'd')
|
||||
tlstate.moveForward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||
|
@ -167,7 +168,6 @@ describe('Move command', () => {
|
|||
|
||||
describe('to front', () => {
|
||||
it('moves a shape to front', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('b')
|
||||
tlstate.moveToFront()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('acdb')
|
||||
|
@ -175,7 +175,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves two adjacent siblings to front', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('a', 'b')
|
||||
tlstate.moveToFront()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('cdab')
|
||||
|
@ -183,7 +182,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves two non-adjacent siblings to front', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('a', 'c')
|
||||
tlstate.moveToFront()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('bdac')
|
||||
|
@ -191,7 +189,6 @@ describe('Move command', () => {
|
|||
})
|
||||
|
||||
it('moves siblings already at front to front', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.select('c', 'd')
|
||||
tlstate.moveToFront()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||
|
|
|
@ -3,10 +3,24 @@ import { mockDocument } from '~test'
|
|||
|
||||
describe('Rotate command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.select('rect1')
|
||||
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when no shape is selected', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.rotate()
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.select('rect1')
|
||||
|
||||
expect(tlstate.getShape('rect1').rotation).toBe(undefined)
|
||||
|
||||
tlstate.rotate()
|
||||
|
|
|
@ -5,8 +5,22 @@ import { mockDocument } from '~test'
|
|||
describe('Stretch command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when less than two shapes are selected', () => {
|
||||
it('does nothing', () => {
|
||||
tlstate.select('rect2')
|
||||
const initialState = tlstate.state
|
||||
tlstate.stretch(StretchType.Horizontal)
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.select('rect1', 'rect2')
|
||||
tlstate.stretch(StretchType.Horizontal)
|
||||
|
||||
|
@ -31,7 +45,6 @@ describe('Stretch command', () => {
|
|||
})
|
||||
|
||||
it('stretches horizontally', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.select('rect1', 'rect2')
|
||||
tlstate.stretch(StretchType.Horizontal)
|
||||
|
||||
|
@ -42,7 +55,6 @@ describe('Stretch command', () => {
|
|||
})
|
||||
|
||||
it('stretches vertically', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.select('rect1', 'rect2')
|
||||
tlstate.stretch(StretchType.Vertical)
|
||||
|
||||
|
|
|
@ -6,9 +6,32 @@ import { ArrowShape, Decoration, TLDrawShape } from '~types'
|
|||
describe('Toggle decoration command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when no shape is selected', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.toggleDecoration('start')
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when handle id is invalid', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.toggleDecoration('invalid')
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate
|
||||
.loadDocument(mockDocument)
|
||||
.create(
|
||||
TLDR.getShapeUtils({ type: 'arrow' } as TLDrawShape).create({
|
||||
id: 'arrow1',
|
||||
|
|
|
@ -5,38 +5,57 @@ import { mockDocument } from '~test'
|
|||
describe('Toggle command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when no shape is selected', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.toggleHidden()
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.selectAll()
|
||||
|
||||
expect(tlstate.getShape('rect2').isAspectRatioLocked).toBe(undefined)
|
||||
expect(tlstate.getShape('rect2').isLocked).toBe(undefined)
|
||||
|
||||
tlstate.toggleAspectRatioLocked()
|
||||
tlstate.toggleLocked()
|
||||
|
||||
expect(tlstate.getShape('rect2').isAspectRatioLocked).toBe(true)
|
||||
expect(tlstate.getShape('rect2').isLocked).toBe(true)
|
||||
|
||||
tlstate.undo()
|
||||
|
||||
expect(tlstate.getShape('rect2').isAspectRatioLocked).toBe(undefined)
|
||||
expect(tlstate.getShape('rect2').isLocked).toBe(undefined)
|
||||
|
||||
tlstate.redo()
|
||||
|
||||
expect(tlstate.getShape('rect2').isAspectRatioLocked).toBe(true)
|
||||
expect(tlstate.getShape('rect2').isLocked).toBe(true)
|
||||
})
|
||||
|
||||
it('toggles on before off when mixed values', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.select('rect2')
|
||||
|
||||
expect(tlstate.getShape<RectangleShape>('rect1').isAspectRatioLocked).toBe(undefined)
|
||||
expect(tlstate.getShape<RectangleShape>('rect2').isAspectRatioLocked).toBe(undefined)
|
||||
|
||||
tlstate.toggleAspectRatioLocked()
|
||||
|
||||
expect(tlstate.getShape<RectangleShape>('rect1').isAspectRatioLocked).toBe(undefined)
|
||||
expect(tlstate.getShape<RectangleShape>('rect2').isAspectRatioLocked).toBe(true)
|
||||
|
||||
tlstate.selectAll()
|
||||
tlstate.toggleAspectRatioLocked()
|
||||
|
||||
expect(tlstate.getShape<RectangleShape>('rect1').isAspectRatioLocked).toBe(true)
|
||||
expect(tlstate.getShape<RectangleShape>('rect1').isAspectRatioLocked).toBe(true)
|
||||
|
||||
tlstate.toggleAspectRatioLocked()
|
||||
|
||||
expect(tlstate.getShape<RectangleShape>('rect1').isAspectRatioLocked).toBe(false)
|
||||
expect(tlstate.getShape<RectangleShape>('rect1').isAspectRatioLocked).toBe(false)
|
||||
})
|
||||
|
|
|
@ -6,8 +6,21 @@ import { ArrowShape, TLDrawShapeType } from '~types'
|
|||
describe('Translate command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when no shape is selected', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.nudge([1, 2])
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.selectAll()
|
||||
tlstate.nudge([1, 2])
|
||||
|
||||
|
@ -23,7 +36,6 @@ describe('Translate command', () => {
|
|||
})
|
||||
|
||||
it('major nudges', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.selectAll()
|
||||
tlstate.nudge([1, 2], true)
|
||||
expect(tlstate.getShape('rect2').point).toEqual([110, 120])
|
||||
|
|
|
@ -1,19 +1,34 @@
|
|||
import { TLDrawState } from '~state'
|
||||
import { mockDocument } from '~test'
|
||||
import { Utils } from '@tldraw/core'
|
||||
|
||||
const doc = Utils.deepClone(mockDocument)
|
||||
|
||||
describe('Update command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
beforeEach(() => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
})
|
||||
|
||||
describe('when no shape is selected', () => {
|
||||
it('does nothing', () => {
|
||||
const initialState = tlstate.state
|
||||
tlstate.updateShapes()
|
||||
const currentState = tlstate.state
|
||||
|
||||
expect(currentState).toEqual(initialState)
|
||||
})
|
||||
})
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.updateShapes({ id: 'rect1', point: [100, 100] })
|
||||
|
||||
expect(tlstate.getShape('rect1').point).toStrictEqual([100, 100])
|
||||
|
||||
tlstate.undo()
|
||||
|
||||
expect(tlstate.getShape('rect1').point).toStrictEqual([0, 0])
|
||||
|
||||
tlstate.redo()
|
||||
|
||||
expect(tlstate.getShape('rect1').point).toStrictEqual([100, 100])
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue