w-flow-vue 1.0.21 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/w-flow-vue.umd.js +3 -3
- package/dist/w-flow-vue.umd.js.map +1 -1
- package/docs/components_WFlowVue.vue.html +61 -6
- package/docs/components_ui_Controls.vue.html +1 -1
- package/docs/examples/app.html +1 -1
- package/docs/examples/app.umd.js +4 -4
- package/docs/examples/app.umd.js.map +1 -1
- package/docs/examples/ex-AppBasic.html +1 -1
- package/docs/examples/ex-AppConnectivity.html +1 -1
- package/docs/global.html +1 -1
- package/docs/index.html +1 -1
- package/docs/js_defaults.mjs.html +1 -1
- package/docs/js_edgePath.mjs.html +1 -1
- package/docs/js_fixSvgNs.mjs.html +1 -1
- package/docs/js_geometry.mjs.html +1 -1
- package/docs/js_graph.mjs.html +1 -1
- package/docs/js_stepRouting.mjs.html +1 -1
- package/docs/module-WFlowVue.html +1 -1
- package/package.json +1 -1
- package/src/components/WFlowVue.vue +60 -5
- package/src/components/nodes/NodeRenderer.vue +1 -0
- package/src/components/nodes/NodeWrapper.vue +81 -19
- package/test/pics/flow-E2E-011-node-settings-form.png +0 -0
- package/test/pics/flow-E2E-012-popup-exclusive.png +0 -0
- package/test/unit-WFlowVue-features.test.mjs +10 -8
- package/test/unit-WFlowVue.test.mjs +432 -421
- package/test/unit-components-canvas.test.mjs +104 -102
- package/test/unit-components-edge.test.mjs +157 -147
- package/test/unit-components-node.test.mjs +27 -5
- package/test/unit-geometry.test.mjs +248 -236
- package/test/unit-graph.test.mjs +72 -72
- package/test/unit-node-drag-gesture.test.mjs +254 -0
|
@@ -1,102 +1,104 @@
|
|
|
1
|
-
import { mount } from '@vue/test-utils'
|
|
2
|
-
import ViewportTransform from '../src/components/canvas/ViewportTransform.vue'
|
|
3
|
-
import SelectionBox from '../src/components/canvas/SelectionBox.vue'
|
|
4
|
-
import BackgroundLayer from '../src/components/canvas/BackgroundLayer.vue'
|
|
5
|
-
import FlowCanvas from '../src/components/canvas/FlowCanvas.vue'
|
|
6
|
-
|
|
7
|
-
describe('ViewportTransform', () => {
|
|
8
|
-
test('applies transform style', () => {
|
|
9
|
-
const wrapper = mount(ViewportTransform, {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
expect(el.
|
|
40
|
-
expect(el.attributes('style')).toContain('
|
|
41
|
-
expect(el.attributes('style')).toContain('
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
wrapper
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import ViewportTransform from '../src/components/canvas/ViewportTransform.vue'
|
|
3
|
+
import SelectionBox from '../src/components/canvas/SelectionBox.vue'
|
|
4
|
+
import BackgroundLayer from '../src/components/canvas/BackgroundLayer.vue'
|
|
5
|
+
import FlowCanvas from '../src/components/canvas/FlowCanvas.vue'
|
|
6
|
+
|
|
7
|
+
describe('ViewportTransform', () => {
|
|
8
|
+
test('applies transform style', () => {
|
|
9
|
+
const wrapper = mount(ViewportTransform, {
|
|
10
|
+
//ViewportTransform 已改收單一 viewport 物件(取代 x/y/zoom 三個純量),
|
|
11
|
+
//目的為令宿主 render 僅讀取穩定物件參考; 斷言意圖(transform 樣式)不變
|
|
12
|
+
propsData: { viewport: { x: 100, y: 50, zoom: 1.5 } },
|
|
13
|
+
slots: { default: '<div class="child">content</div>' },
|
|
14
|
+
})
|
|
15
|
+
expect(wrapper.attributes('style')).toContain('translate(100px, 50px) scale(1.5)')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('default values produce identity transform', () => {
|
|
19
|
+
const wrapper = mount(ViewportTransform, {
|
|
20
|
+
slots: { default: '<div>content</div>' },
|
|
21
|
+
})
|
|
22
|
+
expect(wrapper.attributes('style')).toContain('translate(0px, 0px) scale(1)')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('renders slot content', () => {
|
|
26
|
+
const wrapper = mount(ViewportTransform, {
|
|
27
|
+
slots: { default: '<div class="child">hello</div>' },
|
|
28
|
+
})
|
|
29
|
+
expect(wrapper.find('.child').text()).toBe('hello')
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe('SelectionBox', () => {
|
|
34
|
+
test('renders when box is provided', () => {
|
|
35
|
+
const wrapper = mount(SelectionBox, {
|
|
36
|
+
propsData: { box: { x: 10, y: 20, width: 100, height: 50 } },
|
|
37
|
+
})
|
|
38
|
+
const el = wrapper.find('.vue-flow__selection-box')
|
|
39
|
+
expect(el.exists()).toBe(true)
|
|
40
|
+
expect(el.attributes('style')).toContain('left: 10px')
|
|
41
|
+
expect(el.attributes('style')).toContain('top: 20px')
|
|
42
|
+
expect(el.attributes('style')).toContain('width: 100px')
|
|
43
|
+
expect(el.attributes('style')).toContain('height: 50px')
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('does not render when box is null', () => {
|
|
47
|
+
const wrapper = mount(SelectionBox, {
|
|
48
|
+
propsData: { box: null },
|
|
49
|
+
})
|
|
50
|
+
expect(wrapper.find('.vue-flow__selection-box').exists()).toBe(false)
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
describe('FlowCanvas', () => {
|
|
55
|
+
test('renders container with vue-flow class', () => {
|
|
56
|
+
const wrapper = mount(FlowCanvas, {
|
|
57
|
+
slots: { default: '<div>child</div>' },
|
|
58
|
+
})
|
|
59
|
+
expect(wrapper.classes()).toContain('vue-flow')
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test('emits canvas-click on mousedown+mouseup', () => {
|
|
63
|
+
const wrapper = mount(FlowCanvas)
|
|
64
|
+
wrapper.trigger('mousedown', { clientX: 0, clientY: 0 })
|
|
65
|
+
wrapper.trigger('mouseup', { clientX: 0, clientY: 0 })
|
|
66
|
+
expect(wrapper.emitted('canvas-click')).toBeTruthy()
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
test('emits canvas-mousedown', () => {
|
|
70
|
+
const wrapper = mount(FlowCanvas)
|
|
71
|
+
wrapper.trigger('mousedown', { clientX: 0, clientY: 0 })
|
|
72
|
+
expect(wrapper.emitted('canvas-mousedown')).toBeTruthy()
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('renders slot content', () => {
|
|
76
|
+
const wrapper = mount(FlowCanvas, {
|
|
77
|
+
slots: { default: '<div class="test-child">hello</div>' },
|
|
78
|
+
})
|
|
79
|
+
expect(wrapper.find('.test-child').text()).toBe('hello')
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
describe('BackgroundLayer', () => {
|
|
84
|
+
test('renders svg with pattern', () => {
|
|
85
|
+
const wrapper = mount(BackgroundLayer)
|
|
86
|
+
expect(wrapper.find('svg').exists()).toBe(true)
|
|
87
|
+
expect(wrapper.find('pattern').exists()).toBe(true)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
test('renders dots pattern by default', () => {
|
|
91
|
+
const wrapper = mount(BackgroundLayer, {
|
|
92
|
+
propsData: { variant: 'dots' },
|
|
93
|
+
})
|
|
94
|
+
expect(wrapper.find('circle').exists()).toBe(true)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
test('renders lines pattern', () => {
|
|
98
|
+
const wrapper = mount(BackgroundLayer, {
|
|
99
|
+
propsData: { variant: 'lines' },
|
|
100
|
+
})
|
|
101
|
+
expect(wrapper.find('circle').exists()).toBe(false)
|
|
102
|
+
expect(wrapper.find('path').exists()).toBe(true)
|
|
103
|
+
})
|
|
104
|
+
})
|
|
@@ -1,147 +1,157 @@
|
|
|
1
|
-
import { mount } from '@vue/test-utils'
|
|
2
|
-
import EdgeWrapper from '../src/components/edges/EdgeWrapper.vue'
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
{ id: '
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
|
2
|
+
import EdgeWrapper from '../src/components/edges/EdgeWrapper.vue'
|
|
3
|
+
import EdgeMarkerDefs from '../src/components/edges/EdgeMarkerDefs.vue'
|
|
4
|
+
|
|
5
|
+
describe('EdgeWrapper', () => {
|
|
6
|
+
const baseProps = {
|
|
7
|
+
conn: { id: 'e1-2', source: '1', target: '2', type: 'default' },
|
|
8
|
+
sourceX: 100,
|
|
9
|
+
sourceY: 50,
|
|
10
|
+
targetX: 300,
|
|
11
|
+
targetY: 250,
|
|
12
|
+
sourcePosition: 'bottom',
|
|
13
|
+
targetPosition: 'top',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
test('renders svg group', () => {
|
|
17
|
+
const wrapper = mount(EdgeWrapper, {
|
|
18
|
+
propsData: baseProps,
|
|
19
|
+
})
|
|
20
|
+
expect(wrapper.element.tagName.toLowerCase()).toBe('g')
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('renders path with d attribute', () => {
|
|
24
|
+
const wrapper = mount(EdgeWrapper, {
|
|
25
|
+
propsData: baseProps,
|
|
26
|
+
})
|
|
27
|
+
const paths = wrapper.findAll('path')
|
|
28
|
+
expect(paths.length).toBeGreaterThanOrEqual(1)
|
|
29
|
+
const visiblePath = paths.wrappers.find(p => !p.classes().includes('vue-flow__edge-interaction'))
|
|
30
|
+
expect(visiblePath.attributes('d')).toMatch(/^M /)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
test('applies selected class', () => {
|
|
34
|
+
const wrapper = mount(EdgeWrapper, {
|
|
35
|
+
propsData: { ...baseProps, selected: true },
|
|
36
|
+
})
|
|
37
|
+
expect(wrapper.classes()).toContain('vue-flow__edge--selected')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test('applies animated class', () => {
|
|
41
|
+
const wrapper = mount(EdgeWrapper, {
|
|
42
|
+
propsData: {
|
|
43
|
+
...baseProps,
|
|
44
|
+
conn: { ...baseProps.conn, animated: true },
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
expect(wrapper.classes()).toContain('vue-flow__edge--animated')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
test('renders name when provided', () => {
|
|
51
|
+
const wrapper = mount(EdgeWrapper, {
|
|
52
|
+
propsData: {
|
|
53
|
+
...baseProps,
|
|
54
|
+
conn: { ...baseProps.conn, name: 'test label' },
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
expect(wrapper.find('.vue-flow__edge-label').exists()).toBe(true)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
test('does not render name when not provided', () => {
|
|
61
|
+
const wrapper = mount(EdgeWrapper, {
|
|
62
|
+
propsData: baseProps,
|
|
63
|
+
})
|
|
64
|
+
expect(wrapper.find('.vue-flow__edge-label').exists()).toBe(false)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('emits conn-click on click', () => {
|
|
68
|
+
const wrapper = mount(EdgeWrapper, {
|
|
69
|
+
propsData: baseProps,
|
|
70
|
+
})
|
|
71
|
+
const interactionPath = wrapper.find('.vue-flow__edge-interaction')
|
|
72
|
+
interactionPath.trigger('click')
|
|
73
|
+
expect(wrapper.emitted('conn-click')).toBeTruthy()
|
|
74
|
+
expect(wrapper.emitted('conn-click')[0][0].conn.id).toBe('e1-2')
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
test('renders different edge types', () => {
|
|
78
|
+
const types = ['default', 'straight', 'step', 'smoothstep']
|
|
79
|
+
const paths = types.map(type => {
|
|
80
|
+
const wrapper = mount(EdgeWrapper, {
|
|
81
|
+
propsData: {
|
|
82
|
+
...baseProps,
|
|
83
|
+
conn: { ...baseProps.conn, type },
|
|
84
|
+
},
|
|
85
|
+
})
|
|
86
|
+
const visiblePath = wrapper.findAll('path').wrappers.find(
|
|
87
|
+
p => !p.classes().includes('vue-flow__edge-interaction')
|
|
88
|
+
)
|
|
89
|
+
return visiblePath.attributes('d')
|
|
90
|
+
})
|
|
91
|
+
// straight should differ from bezier
|
|
92
|
+
expect(paths[0]).not.toBe(paths[1])
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
//EdgeLabel.vue 已併入 EdgeWrapper(以 .vue-flow__edge-label 直接渲染 conn.name),
|
|
97
|
+
//故原「連線名稱有被渲染」之斷言改由 EdgeWrapper 驗證
|
|
98
|
+
describe('連線名稱標籤', () => {
|
|
99
|
+
//baseProps 定義於 EdgeWrapper 之 describe 內, 此處自備一份
|
|
100
|
+
const props = {
|
|
101
|
+
sourceX: 100, sourceY: 50, targetX: 300, targetY: 250,
|
|
102
|
+
sourcePosition: 'bottom', targetPosition: 'top',
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
test('conn.name 渲染於 .vue-flow__edge-label', () => {
|
|
106
|
+
const wrapper = mount(EdgeWrapper, {
|
|
107
|
+
propsData: { ...props, conn: { id: 'e1', source: '1', target: '2', name: 'hello' } },
|
|
108
|
+
})
|
|
109
|
+
const label = wrapper.find('.vue-flow__edge-label')
|
|
110
|
+
expect(label.exists()).toBe(true)
|
|
111
|
+
expect(label.text()).toContain('hello')
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
test('無 conn.name 時不渲染標籤', () => {
|
|
115
|
+
const wrapper = mount(EdgeWrapper, {
|
|
116
|
+
propsData: { ...props, conn: { id: 'e1', source: '1', target: '2' } },
|
|
117
|
+
})
|
|
118
|
+
expect(wrapper.find('.vue-flow__edge-label').exists()).toBe(false)
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
describe('EdgeMarkerDefs', () => {
|
|
123
|
+
test('renders marker defs for conns with markers', () => {
|
|
124
|
+
const conns = [
|
|
125
|
+
{ id: 'e1', source: '1', target: '2', markerEnd: 'arrowclosed' },
|
|
126
|
+
{ id: 'e2', source: '2', target: '3', markerEnd: 'arrow' },
|
|
127
|
+
]
|
|
128
|
+
const wrapper = mount(EdgeMarkerDefs, {
|
|
129
|
+
propsData: { conns },
|
|
130
|
+
})
|
|
131
|
+
const markers = wrapper.findAll('marker')
|
|
132
|
+
expect(markers.length).toBe(2)
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
test('deduplicates same marker type', () => {
|
|
136
|
+
const conns = [
|
|
137
|
+
{ id: 'e1', source: '1', target: '2', markerEnd: 'arrowclosed' },
|
|
138
|
+
{ id: 'e2', source: '2', target: '3', markerEnd: 'arrowclosed' },
|
|
139
|
+
]
|
|
140
|
+
const wrapper = mount(EdgeMarkerDefs, {
|
|
141
|
+
propsData: { conns },
|
|
142
|
+
})
|
|
143
|
+
const markers = wrapper.findAll('marker')
|
|
144
|
+
expect(markers.length).toBe(1)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
test('renders no markers when conns have none', () => {
|
|
148
|
+
const conns = [
|
|
149
|
+
{ id: 'e1', source: '1', target: '2' },
|
|
150
|
+
]
|
|
151
|
+
const wrapper = mount(EdgeMarkerDefs, {
|
|
152
|
+
propsData: { conns },
|
|
153
|
+
})
|
|
154
|
+
const markers = wrapper.findAll('marker')
|
|
155
|
+
expect(markers.length).toBe(0)
|
|
156
|
+
})
|
|
157
|
+
})
|
|
@@ -154,16 +154,38 @@ describe('NodeWrapper', () => {
|
|
|
154
154
|
expect(wrapper.emitted('node-click')[0][0].node.id).toBe('1')
|
|
155
155
|
})
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
//拖曳延後至跨越2px位移門檻才啟動: mousedown當下只發drag-prepare(供宿主先行選取),
|
|
158
|
+
//drag-start要有實際位移才發, 否則純點擊會走完endDrag→emit update:nodes而使宿主誤判有未儲存變更
|
|
159
|
+
test('emits drag-prepare (not drag-start) on mousedown when draggable', () => {
|
|
158
160
|
const wrapper = mount(NodeWrapper, { propsData: { node, draggable: true } })
|
|
159
|
-
wrapper.trigger('mousedown')
|
|
160
|
-
expect(wrapper.emitted('drag-
|
|
161
|
+
wrapper.trigger('mousedown', { clientX: 0, clientY: 0, button: 0 })
|
|
162
|
+
expect(wrapper.emitted('drag-prepare')).toBeTruthy()
|
|
163
|
+
expect(wrapper.emitted('drag-start')).toBeFalsy()
|
|
164
|
+
wrapper.destroy()
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
test('emits drag-start once movement crosses the threshold', async () => {
|
|
168
|
+
const wrapper = mount(NodeWrapper, { propsData: { node, draggable: true } })
|
|
169
|
+
wrapper.trigger('mousedown', { clientX: 0, clientY: 0, button: 0 })
|
|
170
|
+
document.dispatchEvent(new MouseEvent('mousemove', { clientX: 20, clientY: 0, buttons: 1 }))
|
|
171
|
+
await wrapper.vm.$nextTick()
|
|
172
|
+
expect(wrapper.emitted('drag-start')).toHaveLength(1)
|
|
173
|
+
wrapper.destroy()
|
|
161
174
|
})
|
|
162
175
|
|
|
163
|
-
test('does not emit drag-start when not draggable', () => {
|
|
176
|
+
test('does not emit drag-prepare or drag-start when not draggable', () => {
|
|
164
177
|
const wrapper = mount(NodeWrapper, { propsData: { node, draggable: false } })
|
|
165
|
-
wrapper.trigger('mousedown')
|
|
178
|
+
wrapper.trigger('mousedown', { clientX: 0, clientY: 0, button: 0 })
|
|
179
|
+
expect(wrapper.emitted('drag-prepare')).toBeFalsy()
|
|
166
180
|
expect(wrapper.emitted('drag-start')).toBeFalsy()
|
|
181
|
+
wrapper.destroy()
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
test('does not emit drag-prepare on non-primary button', () => {
|
|
185
|
+
const wrapper = mount(NodeWrapper, { propsData: { node, draggable: true } })
|
|
186
|
+
wrapper.trigger('mousedown', { clientX: 0, clientY: 0, button: 2 })
|
|
187
|
+
expect(wrapper.emitted('drag-prepare')).toBeFalsy()
|
|
188
|
+
wrapper.destroy()
|
|
167
189
|
})
|
|
168
190
|
|
|
169
191
|
test('applies zIndex from node', () => {
|