Skip to content

Commit b6956e4

Browse files
Add tests for EventSimulationSequenceBuilder
1 parent 52c32c6 commit b6956e4

12 files changed

+839
-33
lines changed

SharpHook.Tests/EventSimulationSequenceBuilderTests.cs

Lines changed: 530 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace SharpHook;
2+
3+
public sealed class EventSimulationSequenceTemplateTests
4+
{
5+
[Property(DisplayName = "Simulate should post events using the simulation provider")]
6+
public void Simulate(NonNull<UioHookEvent[]> events)
7+
{
8+
// Arrange
9+
10+
var eventsToSimulate = events.Get;
11+
12+
var provider = new TestProvider();
13+
var template = new EventSimulationSequenceTemplate(eventsToSimulate, provider);
14+
15+
// Act
16+
17+
template.Simulate();
18+
19+
// Assert
20+
21+
Assert.Equal(eventsToSimulate, provider.PostedEvents);
22+
}
23+
24+
[Fact(DisplayName = "The EventSimulationSequenceTemplate constructor should throw if the events are null")]
25+
public void NullEvents() =>
26+
Assert.Throws<ArgumentNullException>(() => new EventSimulationSequenceTemplate(null!));
27+
}

SharpHook.Tests/Testing/TestGlobalHookTests.cs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,85 @@ public void SimulateTextEntryNull()
13001300
Assert.Throws<ArgumentNullException>(() => hook.SimulateTextEntry(null!));
13011301
}
13021302

1303+
[Property(DisplayName = "Sequence should return an instance of type EventSimulationSequenceBuilder")]
1304+
public void SequenceBuilderType()
1305+
{
1306+
// Arrange
1307+
1308+
var hook = new TestGlobalHook();
1309+
1310+
// Act
1311+
1312+
var builder = hook.Sequence();
1313+
1314+
// Assert
1315+
1316+
Assert.IsType<EventSimulationSequenceBuilder>(builder);
1317+
}
1318+
1319+
[Property(DisplayName = "Sequence builder should post an event back to the test global hook")]
1320+
public void SequenceBuilder(UioHookEvent @event)
1321+
{
1322+
// Arrange
1323+
1324+
var hook = new TestGlobalHook();
1325+
1326+
// Act
1327+
1328+
var result = hook.Sequence()
1329+
.AddEvent(@event)
1330+
.Simulate();
1331+
1332+
// Assert
1333+
1334+
if (@event.Type is EventType.HookEnabled or
1335+
EventType.HookDisabled or
1336+
EventType.KeyTyped or
1337+
EventType.MouseClicked)
1338+
{
1339+
Assert.Empty(hook.SimulatedEvents);
1340+
} else
1341+
{
1342+
Assert.Single(hook.SimulatedEvents);
1343+
Assert.Equal(@event, hook.SimulatedEvents[0]);
1344+
}
1345+
1346+
Assert.Equal(UioHookResult.Success, result);
1347+
}
1348+
1349+
[Property(DisplayName = "Event sequence simulation should be stopped on failure")]
1350+
public void SequenceFailure(KeyboardEvent keyboardEvent, MouseEvent mouseEvent, FailedUioHookResult result)
1351+
{
1352+
// Arrange
1353+
1354+
if (keyboardEvent.Value.Type == EventType.KeyTyped || mouseEvent.Value.Type == EventType.MouseClicked)
1355+
{
1356+
return;
1357+
}
1358+
1359+
var expectedResult = result.Value;
1360+
1361+
var hook = new TestGlobalHook
1362+
{
1363+
SimulateMousePressResult = expectedResult,
1364+
SimulateMouseReleaseResult = expectedResult,
1365+
SimulateMouseMovementResult = expectedResult
1366+
};
1367+
1368+
// Act
1369+
1370+
var actualResult = hook.Sequence()
1371+
.AddEvents(keyboardEvent.Value, mouseEvent.Value)
1372+
.Simulate();
1373+
1374+
// Assert
1375+
1376+
Assert.Single(hook.SimulatedEvents);
1377+
Assert.Equal(keyboardEvent.Value, hook.SimulatedEvents[0]);
1378+
1379+
Assert.Equal(expectedResult, actualResult);
1380+
}
1381+
13031382
[Fact(DisplayName = "EventDateTime should throw on null")]
13041383
public void EventDateTimeNull()
13051384
{

SharpHook.Tests/Testing/TestGlobalHookWithEventLoopTests.cs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,85 @@ public void SimulateTextEntryNull()
13061306
Assert.Throws<ArgumentNullException>(() => hook.SimulateTextEntry(null!));
13071307
}
13081308

1309+
[Property(DisplayName = "Sequence should return an instance of type EventSimulationSequenceBuilder")]
1310+
public void SequenceBuilderType()
1311+
{
1312+
// Arrange
1313+
1314+
var hook = new TestGlobalHook(TestThreadingMode.EventLoop);
1315+
1316+
// Act
1317+
1318+
var builder = hook.Sequence();
1319+
1320+
// Assert
1321+
1322+
Assert.IsType<EventSimulationSequenceBuilder>(builder);
1323+
}
1324+
1325+
[Property(DisplayName = "Sequence builder should post an event back to the test global hook")]
1326+
public void SequenceBuilder(UioHookEvent @event)
1327+
{
1328+
// Arrange
1329+
1330+
var hook = new TestGlobalHook(TestThreadingMode.EventLoop);
1331+
1332+
// Act
1333+
1334+
var result = hook.Sequence()
1335+
.AddEvent(@event)
1336+
.Simulate();
1337+
1338+
// Assert
1339+
1340+
if (@event.Type is EventType.HookEnabled or
1341+
EventType.HookDisabled or
1342+
EventType.KeyTyped or
1343+
EventType.MouseClicked)
1344+
{
1345+
Assert.Empty(hook.SimulatedEvents);
1346+
} else
1347+
{
1348+
Assert.Single(hook.SimulatedEvents);
1349+
Assert.Equal(@event, hook.SimulatedEvents[0]);
1350+
}
1351+
1352+
Assert.Equal(UioHookResult.Success, result);
1353+
}
1354+
1355+
[Property(DisplayName = "Event sequence simulation should be stopped on failure")]
1356+
public void SequenceFailure(KeyboardEvent keyboardEvent, MouseEvent mouseEvent, FailedUioHookResult result)
1357+
{
1358+
// Arrange
1359+
1360+
if (keyboardEvent.Value.Type == EventType.KeyTyped || mouseEvent.Value.Type == EventType.MouseClicked)
1361+
{
1362+
return;
1363+
}
1364+
1365+
var expectedResult = result.Value;
1366+
1367+
var hook = new TestGlobalHook(TestThreadingMode.EventLoop)
1368+
{
1369+
SimulateMousePressResult = expectedResult,
1370+
SimulateMouseReleaseResult = expectedResult,
1371+
SimulateMouseMovementResult = expectedResult
1372+
};
1373+
1374+
// Act
1375+
1376+
var actualResult = hook.Sequence()
1377+
.AddEvents(keyboardEvent.Value, mouseEvent.Value)
1378+
.Simulate();
1379+
1380+
// Assert
1381+
1382+
Assert.Single(hook.SimulatedEvents);
1383+
Assert.Equal(keyboardEvent.Value, hook.SimulatedEvents[0]);
1384+
1385+
Assert.Equal(expectedResult, actualResult);
1386+
}
1387+
13091388
[Fact(DisplayName = "EventDateTime should throw on null")]
13101389
public void EventDateTimeNull()
13111390
{

SharpHook.Tests/Testing/TestProviderTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,23 @@ public void PostEvents(NonEmptyArray<UioHookEvent> events)
541541
}
542542
}
543543

544+
[Property(DisplayName = "PostEvents should do nothing if the array is empty")]
545+
public void PostEventsEmptyArray()
546+
{
547+
// Arrange
548+
549+
var provider = new TestProvider();
550+
551+
// Act
552+
553+
var result = provider.PostEvents([], 0);
554+
555+
// Assert
556+
557+
Assert.Equal(UioHookResult.Success, result);
558+
Assert.Empty(provider.PostedEvents);
559+
}
560+
544561
[Property(DisplayName = "PostEvents should return an error result if configured to do so")]
545562
public void PostEventsError(NonEmptyArray<UioHookEvent> events, FailedUioHookResult result)
546563
{

SharpHook.Tests/Testing/TestProviderWithEventLoopTests.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,27 @@ public void PostEvents(NonEmptyArray<UioHookEvent> events)
526526
}
527527
}
528528

529+
[Property(DisplayName = "PostEvents should do nothing if the array is empty")]
530+
public void PostEventsEmptyArray()
531+
{
532+
// Arrange
533+
534+
var provider = new TestProvider(TestThreadingMode.EventLoop);
535+
536+
// Act
537+
538+
this.RunAndWaitForStart(provider);
539+
540+
var result = provider.PostEvents([], 0);
541+
542+
this.StopAndWaitForStop(provider);
543+
544+
// Assert
545+
546+
Assert.Equal(UioHookResult.Success, result);
547+
Assert.Empty(provider.PostedEvents);
548+
}
549+
529550
[Property(DisplayName = "PostEvents should return an error result if configured to do so")]
530551
public void PostEventsError(NonEmptyArray<UioHookEvent> events, FailedUioHookResult result)
531552
{

SharpHook/EventSimulationSequenceBuilder.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ public IEventSimulationSequenceBuilder AddEvent(UioHookEvent e)
3535
/// </summary>
3636
/// <param name="events">The events to add to the sequence.</param>
3737
/// <returns>The current builder.</returns>
38+
/// <exception cref="ArgumentNullException"><paramref name="events" /> is <see langword="null" />.</exception>
3839
public IEventSimulationSequenceBuilder AddEvents(params UioHookEvent[] events)
3940
{
40-
this.events.AddRange(events);
41+
this.events.AddRange(events ?? throw new ArgumentNullException(nameof(events)));
4142
return this;
4243
}
4344

@@ -46,9 +47,10 @@ public IEventSimulationSequenceBuilder AddEvents(params UioHookEvent[] events)
4647
/// </summary>
4748
/// <param name="events">The events to add to the sequence.</param>
4849
/// <returns>The current builder.</returns>
50+
/// <exception cref="ArgumentNullException"><paramref name="events" /> is <see langword="null" />.</exception>
4951
public IEventSimulationSequenceBuilder AddEvents(IEnumerable<UioHookEvent> events)
5052
{
51-
this.events.AddRange(events);
53+
this.events.AddRange(events ?? throw new ArgumentNullException(nameof(events)));
5254
return this;
5355
}
5456

@@ -242,12 +244,12 @@ public IEventSimulationSequenceBuilder AddMouseMovementRelative(short x, short y
242244
/// used, but it's not required. The value of <paramref name="type" /> is ignored.
243245
/// </para>
244246
/// <para>
245-
/// On macOS it's recommended to use values between <c>-10</c> and <c>10</c>. This will result in quite a small
247+
/// On macOS, it's recommended to use values between <c>-10</c> and <c>10</c>. This will result in quite a small
246248
/// scroll amount with pixel scrolling, so <see cref="MouseWheelScrollType.BlockScroll" /> is recommended for line
247249
/// scrolling instead of pixel scrolling.
248250
/// </para>
249251
/// <para>
250-
/// On Linux there is no fixed recommendation, but multiples of <c>100</c> can be used. The value of
252+
/// On Linux, there is no fixed recommendation, but multiples of <c>100</c> can be used. The value of
251253
/// <paramref name="type" /> is ignored.
252254
/// </para>
253255
/// </remarks>
@@ -279,7 +281,7 @@ public IEventSimulationSequenceBuilder RemoveEvent(UioHookEvent e)
279281
/// <summary>
280282
/// Removes the specified events from the sequence of events to simulate.
281283
/// </summary>
282-
/// <param name="predicate">The predicate to check if the event should be removed from the sequence or not.</param>
284+
/// <param name="predicate">The predicate to check if the event should be removed from the sequence.</param>
283285
/// <returns>The current builder.</returns>
284286
public IEventSimulationSequenceBuilder RemoveEvents(Func<UioHookEvent, bool> predicate)
285287
{

SharpHook/EventSimulator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,12 @@ public UioHookResult SimulateMouseMovementRelative(short x, short y) =>
221221
/// used, but it's not required. The value of <paramref name="type" /> is ignored.
222222
/// </para>
223223
/// <para>
224-
/// On macOS it's recommended to use values between <c>-10</c> and <c>10</c>. This will result in quite a small
224+
/// On macOS, it's recommended to use values between <c>-10</c> and <c>10</c>. This will result in quite a small
225225
/// scroll amount with pixel scrolling, so <see cref="MouseWheelScrollType.BlockScroll" /> is recommended for line
226226
/// scrolling instead of pixel scrolling.
227227
/// </para>
228228
/// <para>
229-
/// On Linux there is no fixed recommendation, but multiples of <c>100</c> can be used. The value of
229+
/// On Linux, there is no fixed recommendation, but multiples of <c>100</c> can be used. The value of
230230
/// <paramref name="type" /> is ignored.
231231
/// </para>
232232
/// </remarks>

SharpHook/IEventSimulationSequenceBuilder.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ public interface IEventSimulationSequenceBuilder
1717
/// </summary>
1818
/// <param name="events">The events to add to the sequence.</param>
1919
/// <returns>The current builder.</returns>
20+
/// <exception cref="ArgumentNullException"><paramref name="events" /> is <see langword="null" />.</exception>
2021
IEventSimulationSequenceBuilder AddEvents(params UioHookEvent[] events);
2122

2223
/// <summary>
2324
/// Adds the specified events to the sequence of events to simulate.
2425
/// </summary>
2526
/// <param name="events">The events to add to the sequence.</param>
2627
/// <returns>The current builder.</returns>
28+
/// <exception cref="ArgumentNullException"><paramref name="events" /> is <see langword="null" />.</exception>
2729
IEventSimulationSequenceBuilder AddEvents(IEnumerable<UioHookEvent> events);
2830

2931
/// <summary>
@@ -140,12 +142,12 @@ public interface IEventSimulationSequenceBuilder
140142
/// used, but it's not required. The value of <paramref name="type" /> is ignored.
141143
/// </para>
142144
/// <para>
143-
/// On macOS it's recommended to use values between <c>-10</c> and <c>10</c>. This will result in quite a small
145+
/// On macOS, it's recommended to use values between <c>-10</c> and <c>10</c>. This will result in quite a small
144146
/// scroll amount with pixel scrolling, so <see cref="MouseWheelScrollType.BlockScroll" /> is recommended for line
145147
/// scrolling instead of pixel scrolling.
146148
/// </para>
147149
/// <para>
148-
/// On Linux there is no fixed recommendation, but multiples of <c>100</c> can be used. The value of
150+
/// On Linux, there is no fixed recommendation, but multiples of <c>100</c> can be used. The value of
149151
/// <paramref name="type" /> is ignored.
150152
/// </para>
151153
/// </remarks>
@@ -154,6 +156,20 @@ IEventSimulationSequenceBuilder AddMouseWheel(
154156
MouseWheelScrollDirection direction = MouseWheelScrollDirection.Vertical,
155157
MouseWheelScrollType type = MouseWheelScrollType.UnitScroll);
156158

159+
/// <summary>
160+
/// Removes the specified event from the sequence of events to simulate.
161+
/// </summary>
162+
/// <param name="e">The event to remove from the sequence.</param>
163+
/// <returns>The current builder.</returns>
164+
IEventSimulationSequenceBuilder RemoveEvent(UioHookEvent e);
165+
166+
/// <summary>
167+
/// Removes the specified events from the sequence of events to simulate.
168+
/// </summary>
169+
/// <param name="predicate">The predicate to check if the event should be removed from the sequence.</param>
170+
/// <returns>The current builder.</returns>
171+
IEventSimulationSequenceBuilder RemoveEvents(Func<UioHookEvent, bool> predicate);
172+
157173
/// <summary>
158174
/// Simulates the events in this sequence.
159175
/// </summary>

SharpHook/IEventSimulator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ public interface IEventSimulator
141141
/// <returns>The result of the operation.</returns>
142142
/// <remarks>
143143
/// <para>
144-
/// On Windows, the value <c>120</c> represents the default wheel step. As such, multiples of <c>120</c> can be used,
145-
/// but it's not required. The value of <paramref name="type" /> is ignored.
144+
/// On Windows, the value <c>120</c> represents the default wheel step. As such, multiples of <c>120</c> can be
145+
/// used, but it's not required. The value of <paramref name="type" /> is ignored.
146146
/// </para>
147147
/// <para>
148148
/// On macOS, it's recommended to use values between <c>-10</c> and <c>10</c>. This will result in quite a small

0 commit comments

Comments
 (0)