Skip to content

Commit 605028d

Browse files
authored
Merge pull request #371 from K0369/bugfix/#359-should-delete-constraint-not-checked-on-remove-control
Bugfix/#359 should delete constraint not checked on remove control
2 parents 2209b52 + e586245 commit 605028d

File tree

2 files changed

+303
-5
lines changed

2 files changed

+303
-5
lines changed

src/Blazor.Diagrams.Core/Controls/Default/RemoveControl.cs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,44 @@ public RemoveControl(IPositionProvider positionProvider)
2323

2424
public override Point? GetPosition(Model model) => _positionProvider.GetPosition(model);
2525

26-
public override ValueTask OnPointerDown(Diagram diagram, Model model, PointerEventArgs _)
26+
public override async ValueTask OnPointerDown(Diagram diagram, Model model, PointerEventArgs _)
2727
{
28-
switch (model)
28+
if (await ShouldDeleteModel(diagram, model))
2929
{
30+
DeleteModel(diagram, model);
31+
}
32+
}
33+
34+
private static void DeleteModel(Diagram diagram, Model model)
35+
{
36+
switch (model)
37+
{
38+
case GroupModel group:
39+
diagram.Groups.Delete(group);
40+
return;
3041
case NodeModel node:
3142
diagram.Nodes.Remove(node);
32-
break;
43+
return;
44+
3345
case BaseLinkModel link:
3446
diagram.Links.Remove(link);
35-
break;
47+
return;
48+
}
49+
}
50+
51+
private static async ValueTask<bool> ShouldDeleteModel(Diagram diagram, Model model)
52+
{
53+
if (model.Locked)
54+
{
55+
return false;
3656
}
3757

38-
return ValueTask.CompletedTask;
58+
return model switch
59+
{
60+
GroupModel group => await diagram.Options.Constraints.ShouldDeleteGroup.Invoke(group),
61+
NodeModel node => await diagram.Options.Constraints.ShouldDeleteNode.Invoke(node),
62+
BaseLinkModel link => await diagram.Options.Constraints.ShouldDeleteLink.Invoke(link),
63+
_ => false,
64+
};
3965
}
4066
}
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
using Blazor.Diagrams.Core.Controls.Default;
2+
using Blazor.Diagrams.Core.Events;
3+
using Blazor.Diagrams.Core.Geometry;
4+
using Blazor.Diagrams.Core.Models;
5+
using Blazor.Diagrams.Core.Models.Base;
6+
using Moq;
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Linq;
10+
using System.Text;
11+
using System.Threading.Tasks;
12+
using Xunit;
13+
14+
namespace Blazor.Diagrams.Core.Tests.Controls
15+
{
16+
public class RemoveControlTests
17+
{
18+
public PointerEventArgs PointerEventArgs
19+
=> new(100, 100, 0, 0, false, false, false, 0, 0, 0, 0, 0, 0, string.Empty, true);
20+
21+
[Fact]
22+
public async Task OnPointerDown_NoConstraints_RemovesNode()
23+
{
24+
// Arrange
25+
RemoveControl removeControl = new(0, 0);
26+
Diagram diagram = new TestDiagram();
27+
var nodeMock = new Mock<NodeModel>(Point.Zero);
28+
var node = diagram.Nodes.Add(nodeMock.Object);
29+
30+
// Act
31+
await removeControl.OnPointerDown(diagram, node, PointerEventArgs);
32+
33+
// Assert
34+
Assert.Empty(diagram.Nodes);
35+
}
36+
37+
[Fact]
38+
public async Task OnPointerDown_ShouldDeleteNodeTrue_RemovesNode()
39+
{
40+
// Arrange
41+
RemoveControl removeControl = new(0, 0);
42+
Diagram diagram = new TestDiagram(
43+
new Options.DiagramOptions
44+
{
45+
Constraints =
46+
{
47+
ShouldDeleteNode = (node) => ValueTask.FromResult(true)
48+
}
49+
});
50+
var nodeMock = new Mock<NodeModel>(Point.Zero);
51+
var node = diagram.Nodes.Add(nodeMock.Object);
52+
53+
// Act
54+
await removeControl.OnPointerDown(diagram, node, PointerEventArgs);
55+
56+
// Assert
57+
Assert.Empty(diagram.Nodes);
58+
}
59+
60+
[Fact]
61+
public async Task OnPointerDown_ShouldDeleteNodeFalse_KeepsNode()
62+
{
63+
// Arrange
64+
RemoveControl removeControl = new(0, 0);
65+
Diagram diagram = new TestDiagram(
66+
new Options.DiagramOptions
67+
{
68+
Constraints =
69+
{
70+
ShouldDeleteNode = (node) => ValueTask.FromResult(false)
71+
}
72+
});
73+
var nodeMock = new Mock<NodeModel>(Point.Zero);
74+
var node = diagram.Nodes.Add(nodeMock.Object);
75+
76+
// Act
77+
await removeControl.OnPointerDown(diagram, node, PointerEventArgs);
78+
79+
// Assert
80+
Assert.Contains(node, diagram.Nodes);
81+
}
82+
83+
[Fact]
84+
public async Task OnPointerDown_NoConstraints_RemovesLink()
85+
{
86+
// Arrange
87+
RemoveControl removeControl = new(0, 0);
88+
Diagram diagram = new TestDiagram();
89+
90+
var node1 = new NodeModel(new Point(50, 50));
91+
var node2 = new NodeModel(new Point(300, 300));
92+
diagram.Nodes.Add(new[] { node1, node2 });
93+
node1.AddPort(PortAlignment.Right);
94+
node2.AddPort(PortAlignment.Left);
95+
96+
var link = new LinkModel(
97+
node1.GetPort(PortAlignment.Right)!,
98+
node2.GetPort(PortAlignment.Left)!
99+
);
100+
101+
diagram.Links.Add(link);
102+
103+
// Act
104+
await removeControl.OnPointerDown(diagram, link, PointerEventArgs);
105+
106+
// Assert
107+
Assert.Empty(diagram.Links);
108+
}
109+
110+
[Fact]
111+
public async Task OnPointerDown_ShouldDeleteLinkTrue_RemovesLink()
112+
{
113+
// Arrange
114+
RemoveControl removeControl = new(0, 0);
115+
Diagram diagram = new TestDiagram(
116+
new Options.DiagramOptions
117+
{
118+
Constraints =
119+
{
120+
ShouldDeleteLink = (node) => ValueTask.FromResult(true)
121+
}
122+
});
123+
124+
var node1 = new NodeModel(new Point(50, 50));
125+
var node2 = new NodeModel(new Point(300, 300));
126+
diagram.Nodes.Add(new[] { node1, node2 });
127+
node1.AddPort(PortAlignment.Right);
128+
node2.AddPort(PortAlignment.Left);
129+
130+
var link = new LinkModel(
131+
node1.GetPort(PortAlignment.Right)!,
132+
node2.GetPort(PortAlignment.Left)!
133+
);
134+
135+
diagram.Links.Add(link);
136+
137+
// Act
138+
await removeControl.OnPointerDown(diagram, link, PointerEventArgs);
139+
140+
// Assert
141+
Assert.Empty(diagram.Links);
142+
}
143+
144+
[Fact]
145+
public async Task OnPointerDown_ShouldDeleteLinkFalse_KeepsLink()
146+
{
147+
// Arrange
148+
RemoveControl removeControl = new(0, 0);
149+
Diagram diagram = new TestDiagram(
150+
new Options.DiagramOptions
151+
{
152+
Constraints =
153+
{
154+
ShouldDeleteLink = (node) => ValueTask.FromResult(false)
155+
}
156+
});
157+
158+
var node1 = new NodeModel(new Point(50, 50));
159+
var node2 = new NodeModel(new Point(300, 300));
160+
diagram.Nodes.Add(new[] { node1, node2 });
161+
node1.AddPort(PortAlignment.Right);
162+
node2.AddPort(PortAlignment.Left);
163+
164+
var link = new LinkModel(
165+
node1.GetPort(PortAlignment.Right)!,
166+
node2.GetPort(PortAlignment.Left)!
167+
);
168+
169+
diagram.Links.Add(link);
170+
171+
// Act
172+
await removeControl.OnPointerDown(diagram, link, PointerEventArgs);
173+
174+
// Assert
175+
Assert.Contains(link, diagram.Links);
176+
}
177+
178+
[Fact]
179+
public async Task OnPointerDown_NoConstraints_RemovesGroup()
180+
{
181+
// Arrange
182+
RemoveControl removeControl = new(0, 0);
183+
Diagram diagram = new TestDiagram();
184+
185+
var node1 = new NodeModel(new Point(50, 50));
186+
var node2 = new NodeModel(new Point(300, 300));
187+
diagram.Nodes.Add(new[] { node1, node2 });
188+
node1.AddPort(PortAlignment.Right);
189+
node2.AddPort(PortAlignment.Left);
190+
191+
var group = new GroupModel(new[] { node1, node2 });
192+
193+
194+
diagram.Groups.Add(group);
195+
196+
// Act
197+
await removeControl.OnPointerDown(diagram, group, PointerEventArgs);
198+
199+
// Assert
200+
Assert.Empty(diagram.Groups);
201+
Assert.Empty(diagram.Nodes);
202+
}
203+
204+
[Fact]
205+
public async Task OnPointerDown_ShouldDeleteGroupTrue_RemovesGroup()
206+
{
207+
// Arrange
208+
RemoveControl removeControl = new(0, 0);
209+
Diagram diagram = new TestDiagram(
210+
new Options.DiagramOptions
211+
{
212+
Constraints =
213+
{
214+
ShouldDeleteGroup = (node) => ValueTask.FromResult(true)
215+
}
216+
});
217+
218+
var node1 = new NodeModel(new Point(50, 50));
219+
var node2 = new NodeModel(new Point(300, 300));
220+
diagram.Nodes.Add(new[] { node1, node2 });
221+
node1.AddPort(PortAlignment.Right);
222+
node2.AddPort(PortAlignment.Left);
223+
224+
var group = new GroupModel(new[] { node1, node2 });
225+
226+
227+
diagram.Groups.Add(group);
228+
229+
// Act
230+
await removeControl.OnPointerDown(diagram, group, PointerEventArgs);
231+
232+
// Assert
233+
Assert.Empty(diagram.Groups);
234+
Assert.Empty(diagram.Nodes);
235+
}
236+
237+
[Fact]
238+
public async Task OnPointerDown_ShouldDeleteGroupFalse_KeepsGroup()
239+
{
240+
// Arrange
241+
RemoveControl removeControl = new(0, 0);
242+
Diagram diagram = new TestDiagram(
243+
new Options.DiagramOptions
244+
{
245+
Constraints =
246+
{
247+
ShouldDeleteGroup = (node) => ValueTask.FromResult(false)
248+
}
249+
});
250+
251+
var node1 = new NodeModel(new Point(50, 50));
252+
var node2 = new NodeModel(new Point(300, 300));
253+
diagram.Nodes.Add(new[] { node1, node2 });
254+
node1.AddPort(PortAlignment.Right);
255+
node2.AddPort(PortAlignment.Left);
256+
257+
var group = new GroupModel(new[] { node1, node2 });
258+
259+
260+
diagram.Groups.Add(group);
261+
262+
// Act
263+
await removeControl.OnPointerDown(diagram, group, PointerEventArgs);
264+
265+
// Assert
266+
Assert.Contains(group, diagram.Groups);
267+
Assert.Contains(node1, diagram.Nodes);
268+
Assert.Contains(node2, diagram.Nodes);
269+
}
270+
271+
}
272+
}

0 commit comments

Comments
 (0)