Skip to content

Commit d656ede

Browse files
committed
Merge branch 'Thevin' into dev
2 parents 9e91926 + 9dd365f commit d656ede

19 files changed

Lines changed: 408 additions & 199 deletions

EliteAPI.Tests/FileWatcherTests.cs

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
using EliteAPI.Watcher;
2+
using FluentAssertions;
3+
4+
namespace EliteAPI.Tests;
5+
6+
public class FileWatcherTests
7+
{
8+
private DirectoryInfo _testDirectory = null!;
9+
10+
[Before(HookType.Test)]
11+
public async Task Setup()
12+
{
13+
_testDirectory = Directory.CreateTempSubdirectory("EliteAPI_FileWatcher_Tests");
14+
}
15+
16+
[After(HookType.Test)]
17+
public async Task Cleanup()
18+
{
19+
if (_testDirectory.Exists)
20+
_testDirectory.Delete(recursive: true);
21+
}
22+
23+
[Test]
24+
public async Task EntireFileWatcher_Create_ReturnsInitialContent()
25+
{
26+
var testFile = new FileInfo(Path.Combine(_testDirectory.FullName, "test.txt"));
27+
await File.WriteAllTextAsync(testFile.FullName, "Initial content");
28+
29+
var (watcher, initialContent) = EntireFileWatcher.Create(testFile);
30+
31+
initialContent.Should().Be("Initial content");
32+
watcher.Should().NotBeNull();
33+
}
34+
35+
[Test]
36+
public async Task EntireFileWatcher_OnChange_EmitsEntireFileContent()
37+
{
38+
var testFile = new FileInfo(Path.Combine(_testDirectory.FullName, "test.txt"));
39+
await File.WriteAllTextAsync(testFile.FullName, "Initial content");
40+
41+
var (watcher, _) = EntireFileWatcher.Create(testFile);
42+
var changedContent = "";
43+
var tcs = new TaskCompletionSource<bool>();
44+
45+
watcher.OnChange(content =>
46+
{
47+
changedContent = content;
48+
tcs.TrySetResult(true);
49+
});
50+
51+
await Task.Delay(100); // Give watcher time to start
52+
await File.WriteAllTextAsync(testFile.FullName, "Updated content");
53+
54+
await Task.WhenAny(tcs.Task, Task.Delay(5000));
55+
56+
changedContent.Should().Be("Updated content");
57+
}
58+
59+
[Test]
60+
public async Task LineByLineFileWatcher_Create_ReturnsInitialLines()
61+
{
62+
var testFile = new FileInfo(Path.Combine(_testDirectory.FullName, "test.txt"));
63+
await File.WriteAllLinesAsync(testFile.FullName, ["Line 1", "Line 2", "Line 3"]);
64+
65+
var (watcher, initialContent) = LineByLineFileWatcher.Create(testFile);
66+
67+
initialContent.Should().BeEquivalentTo(["Line 1", "Line 2", "Line 3"]);
68+
watcher.Should().NotBeNull();
69+
}
70+
71+
[Test]
72+
public async Task LineByLineFileWatcher_OnChange_EmitsOnlyNewLines()
73+
{
74+
var testFile = new FileInfo(Path.Combine(_testDirectory.FullName, "test.txt"));
75+
await File.WriteAllLinesAsync(testFile.FullName, ["Line 1", "Line 2"]);
76+
77+
var (watcher, _) = LineByLineFileWatcher.Create(testFile);
78+
var newLines = new List<string>();
79+
var tcs = new TaskCompletionSource<bool>();
80+
var expectedNewLines = 2;
81+
82+
watcher.OnChange(line =>
83+
{
84+
newLines.Add(line);
85+
if (newLines.Count >= expectedNewLines)
86+
tcs.TrySetResult(true);
87+
});
88+
89+
await Task.Delay(100); // Give watcher time to start
90+
await File.WriteAllLinesAsync(testFile.FullName, ["Line 1", "Line 2", "Line 3", "Line 4"]);
91+
92+
await Task.WhenAny(tcs.Task, Task.Delay(5000));
93+
94+
newLines.Should().BeEquivalentTo(["Line 3", "Line 4"]);
95+
}
96+
97+
[Test]
98+
public async Task LineByLineFileWatcher_OnChange_HandlesMultipleChanges()
99+
{
100+
var testFile = new FileInfo(Path.Combine(_testDirectory.FullName, "test.txt"));
101+
await File.WriteAllLinesAsync(testFile.FullName, ["Line 1"]);
102+
103+
var (watcher, _) = LineByLineFileWatcher.Create(testFile);
104+
var allNewLines = new List<string>();
105+
var tcs = new TaskCompletionSource<bool>();
106+
var expectedTotalLines = 3; // Line 2, Line 3, Line 4
107+
108+
watcher.OnChange(line =>
109+
{
110+
allNewLines.Add(line);
111+
if (allNewLines.Count >= expectedTotalLines)
112+
tcs.TrySetResult(true);
113+
});
114+
115+
await Task.Delay(100);
116+
await File.WriteAllLinesAsync(testFile.FullName, ["Line 1", "Line 2"]);
117+
118+
await Task.Delay(200);
119+
await File.WriteAllLinesAsync(testFile.FullName, ["Line 1", "Line 2", "Line 3", "Line 4"]);
120+
121+
await Task.WhenAny(tcs.Task, Task.Delay(5000));
122+
123+
allNewLines.Should().BeEquivalentTo(["Line 2", "Line 3", "Line 4"]);
124+
}
125+
126+
[Test]
127+
public async Task LineByLineFileWatcher_OnChange_DoesNotEmitWhenNoNewLines()
128+
{
129+
var testFile = new FileInfo(Path.Combine(_testDirectory.FullName, "test.txt"));
130+
await File.WriteAllLinesAsync(testFile.FullName, ["Line 1", "Line 2"]);
131+
132+
var (watcher, _) = LineByLineFileWatcher.Create(testFile);
133+
var newLines = new List<string>();
134+
135+
watcher.OnChange(line =>
136+
{
137+
newLines.Add(line);
138+
});
139+
140+
await Task.Delay(100);
141+
// Trigger file change but don't add new lines
142+
await File.WriteAllLinesAsync(testFile.FullName, ["Line 1", "Line 2"]);
143+
144+
await Task.Delay(500);
145+
146+
newLines.Should().BeEmpty();
147+
}
148+
}

EliteAPI.Tests/Flattening.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public void DateTimeField()
107107

108108
var expected = new[]
109109
{
110-
new JsonPath("timestamp", DateTime.Parse("2025-11-21T10:30:00Z"), JsonType.DateTime)
110+
new JsonPath("timestamp", new DateTime(2025, 11, 21, 10, 30, 0, DateTimeKind.Utc), JsonType.DateTime)
111111
};
112112

113113
paths.Should().BeEquivalentTo(expected);
@@ -121,8 +121,8 @@ public void MultipleDateTimeFields()
121121

122122
var expected = new[]
123123
{
124-
new JsonPath("createdAt", DateTime.Parse("2025-11-21T10:30:00Z"), JsonType.DateTime),
125-
new JsonPath("updatedAt", DateTime.Parse("2025-11-21T15:45:00Z"), JsonType.DateTime)
124+
new JsonPath("createdAt", new DateTime(2025, 11, 21, 10, 30, 0, DateTimeKind.Utc), JsonType.DateTime),
125+
new JsonPath("updatedAt", new DateTime(2025, 11, 21, 15, 45, 0, DateTimeKind.Utc), JsonType.DateTime)
126126
};
127127

128128
paths.Should().BeEquivalentTo(expected);
@@ -139,7 +139,7 @@ public void MixedTypesWithDecimalAndDateTime()
139139
new JsonPath("id", 1, JsonType.Number),
140140
new JsonPath("name", "Product", JsonType.String),
141141
new JsonPath("price", 29.99m, JsonType.Decimal),
142-
new JsonPath("created", DateTime.Parse("2025-11-21T10:00:00Z"), JsonType.DateTime),
142+
new JsonPath("created", new DateTime(2025, 11, 21, 10, 0, 0, DateTimeKind.Utc), JsonType.DateTime),
143143
new JsonPath("active", true, JsonType.Boolean)
144144
};
145145

@@ -186,7 +186,7 @@ public void NestedObjectWithMixedTypes()
186186
new JsonPath("product.id", 1, JsonType.Number),
187187
new JsonPath("product.name", "Widget", JsonType.String),
188188
new JsonPath("product.price", 19.99m, JsonType.Decimal),
189-
new JsonPath("product.created", DateTime.Parse("2025-11-21T10:00:00Z"), JsonType.DateTime),
189+
new JsonPath("product.created", new DateTime(2025, 11, 21, 10, 0, 0, DateTimeKind.Utc), JsonType.DateTime),
190190
new JsonPath("product.inStock", true, JsonType.Boolean)
191191
};
192192

@@ -220,7 +220,7 @@ public void NestedObjectWithDecimalAndDateTime()
220220
{
221221
new JsonPath("transaction.amount", 99.99m, JsonType.Decimal),
222222
new JsonPath("transaction.fee", 2.50m, JsonType.Decimal),
223-
new JsonPath("transaction.timestamp", DateTime.Parse("2025-11-21T14:30:00Z"), JsonType.DateTime)
223+
new JsonPath("transaction.timestamp", new DateTime(2025, 11, 21, 14, 30, 0, DateTimeKind.Utc), JsonType.DateTime)
224224
};
225225

226226
paths.Should().BeEquivalentTo(expected);
@@ -277,7 +277,7 @@ public void ComplexNestedStructure()
277277
new JsonPath("order.items[1].price", 25.99m, JsonType.Decimal),
278278
new JsonPath("order.items.Length", 2, JsonType.Number),
279279
new JsonPath("order.total", 36.49m, JsonType.Decimal),
280-
new JsonPath("order.orderDate", DateTime.Parse("2025-11-21T09:00:00Z"), JsonType.DateTime)
280+
new JsonPath("order.orderDate", new DateTime(2025, 11, 21, 9, 0, 0, DateTimeKind.Utc), JsonType.DateTime)
281281
};
282282

283283
paths.Should().BeEquivalentTo(expected);
@@ -408,9 +408,9 @@ public void ArrayOfDateTimes()
408408

409409
var expected = new[]
410410
{
411-
new JsonPath("timestamps[0]", DateTime.Parse("2025-11-21T10:00:00Z"), JsonType.DateTime),
412-
new JsonPath("timestamps[1]", DateTime.Parse("2025-11-21T11:00:00Z"), JsonType.DateTime),
413-
new JsonPath("timestamps[2]", DateTime.Parse("2025-11-21T12:00:00Z"), JsonType.DateTime),
411+
new JsonPath("timestamps[0]", new DateTime(2025, 11, 21, 10, 0, 0, DateTimeKind.Utc), JsonType.DateTime),
412+
new JsonPath("timestamps[1]", new DateTime(2025, 11, 21, 11, 0, 0, DateTimeKind.Utc), JsonType.DateTime),
413+
new JsonPath("timestamps[2]", new DateTime(2025, 11, 21, 12, 0, 0, DateTimeKind.Utc), JsonType.DateTime),
414414
new JsonPath("timestamps.Length", 3, JsonType.Number)
415415
};
416416

EliteAPI/Class1.cs

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)