Skip to content

Commit ace6550

Browse files
committed
Extend Ecng.Data coverage: connection cache edge cases and pair equality
1 parent f782892 commit ace6550

1 file changed

Lines changed: 347 additions & 2 deletions

File tree

Tests/Data/DataTests.cs

Lines changed: 347 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
namespace Ecng.Tests.Data;
1+
namespace Ecng.Tests.Data;
22

33
using Ecng.Data;
44
using Ecng.Serialization;
55

66
[TestClass]
7-
public class DataTests
7+
public class DataTests : BaseTestClass
88
{
99
[TestMethod]
1010
public void AddRemove()
@@ -37,4 +37,349 @@ public void SaveLoad()
3737
pair2.Provider.AssertEqual(pair.Provider);
3838
pair2.ConnectionString.AssertEqual(pair.ConnectionString);
3939
}
40+
41+
[TestMethod]
42+
public void GetOrAddIsIdempotent()
43+
{
44+
var cache = new DatabaseConnectionCache();
45+
var created = 0;
46+
cache.ConnectionCreated += p => created++;
47+
48+
var first = cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, "Server=localhost");
49+
var second = cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, "Server=localhost");
50+
51+
AreSame(first, second);
52+
cache.Connections.Count().AssertEqual(1);
53+
created.AssertEqual(1);
54+
}
55+
56+
[TestMethod]
57+
public void GetOrAddIsCaseInsensitive()
58+
{
59+
var cache = new DatabaseConnectionCache();
60+
var first = cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, "Server=Localhost");
61+
var second = cache.GetOrAdd(DatabaseProviderRegistry.SqlServer.ToLower(), "server=localhost");
62+
63+
AreSame(first, second);
64+
cache.Connections.Count().AssertEqual(1);
65+
}
66+
67+
[TestMethod]
68+
public void GetOrAddDifferentConnectionStringsSameProvider()
69+
{
70+
var cache = new DatabaseConnectionCache();
71+
var a = cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, "Server=A");
72+
var b = cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, "Server=B");
73+
74+
AreNotSame(a, b);
75+
cache.Connections.Count().AssertEqual(2);
76+
}
77+
78+
[TestMethod]
79+
public void GetOrAddDifferentProvidersSameConnectionString()
80+
{
81+
var cache = new DatabaseConnectionCache();
82+
var a = cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, "shared");
83+
var b = cache.GetOrAdd(DatabaseProviderRegistry.SQLite, "shared");
84+
85+
AreNotSame(a, b);
86+
cache.Connections.Count().AssertEqual(2);
87+
}
88+
89+
[TestMethod]
90+
public void GetOrAddNullProviderThrows()
91+
{
92+
var cache = new DatabaseConnectionCache();
93+
ThrowsExactly<ArgumentNullException>(() => cache.GetOrAdd(null, "cs"));
94+
}
95+
96+
[TestMethod]
97+
public void GetOrAddEmptyProviderThrows()
98+
{
99+
var cache = new DatabaseConnectionCache();
100+
ThrowsExactly<ArgumentNullException>(() => cache.GetOrAdd(string.Empty, "cs"));
101+
}
102+
103+
[TestMethod]
104+
public void GetOrAddNullConnectionStringThrows()
105+
{
106+
var cache = new DatabaseConnectionCache();
107+
ThrowsExactly<ArgumentNullException>(() => cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, null));
108+
}
109+
110+
[TestMethod]
111+
public void GetOrAddEmptyConnectionStringThrows()
112+
{
113+
var cache = new DatabaseConnectionCache();
114+
ThrowsExactly<ArgumentNullException>(() => cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, string.Empty));
115+
}
116+
117+
[TestMethod]
118+
public void DeleteConnectionNullThrows()
119+
{
120+
var cache = new DatabaseConnectionCache();
121+
ThrowsExactly<ArgumentNullException>(() => cache.DeleteConnection(null));
122+
}
123+
124+
[TestMethod]
125+
public void DeleteConnectionTwiceFiresEventOnce()
126+
{
127+
var cache = new DatabaseConnectionCache();
128+
var deleted = 0;
129+
cache.ConnectionDeleted += p => deleted++;
130+
131+
var pair = cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, "cs");
132+
133+
var firstResult = cache.DeleteConnection(pair);
134+
var secondResult = cache.DeleteConnection(pair);
135+
136+
firstResult.AssertTrue();
137+
secondResult.AssertFalse();
138+
deleted.AssertEqual(1);
139+
cache.Connections.Count().AssertEqual(0);
140+
}
141+
142+
[TestMethod]
143+
public void DeleteConnectionUnknownReturnsFalse()
144+
{
145+
var cache = new DatabaseConnectionCache();
146+
var deleted = 0;
147+
cache.ConnectionDeleted += p => deleted++;
148+
149+
var orphan = new DatabaseConnectionPair
150+
{
151+
Provider = DatabaseProviderRegistry.SqlServer,
152+
ConnectionString = "not-in-cache",
153+
};
154+
155+
cache.DeleteConnection(orphan).AssertFalse();
156+
deleted.AssertEqual(0);
157+
}
158+
159+
[TestMethod]
160+
public void UpdatedEventFiresOnAddAndDelete()
161+
{
162+
var cache = new DatabaseConnectionCache();
163+
var updated = 0;
164+
cache.Updated += () => updated++;
165+
166+
var pair = cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, "cs");
167+
updated.AssertEqual(1);
168+
169+
cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, "cs");
170+
updated.AssertEqual(1);
171+
172+
cache.DeleteConnection(pair);
173+
updated.AssertEqual(2);
174+
175+
cache.DeleteConnection(pair);
176+
updated.AssertEqual(2);
177+
}
178+
179+
[TestMethod]
180+
public void ConnectionCreatedReceivesCorrectPair()
181+
{
182+
var cache = new DatabaseConnectionCache();
183+
DatabaseConnectionPair received = null;
184+
cache.ConnectionCreated += p => received = p;
185+
186+
var pair = cache.GetOrAdd(DatabaseProviderRegistry.SQLite, "Data Source=test.db");
187+
188+
AreSame(pair, received);
189+
}
190+
191+
[TestMethod]
192+
public void ConnectionDeletedReceivesCorrectPair()
193+
{
194+
var cache = new DatabaseConnectionCache();
195+
DatabaseConnectionPair received = null;
196+
cache.ConnectionDeleted += p => received = p;
197+
198+
var pair = cache.GetOrAdd(DatabaseProviderRegistry.SQLite, "Data Source=test.db");
199+
cache.DeleteConnection(pair);
200+
201+
AreSame(pair, received);
202+
}
203+
204+
[TestMethod]
205+
public void SaveLoadEmptyCache()
206+
{
207+
var cache = new DatabaseConnectionCache();
208+
var ser = new JsonSerializer<DatabaseConnectionCache>();
209+
210+
var restored = ser.Deserialize(ser.Serialize(cache));
211+
212+
IsNotNull(restored);
213+
restored.Connections.Count().AssertEqual(0);
214+
}
215+
216+
[TestMethod]
217+
public void SaveLoadMultipleConnectionsRoundTrip()
218+
{
219+
var cache = new DatabaseConnectionCache();
220+
cache.GetOrAdd(DatabaseProviderRegistry.SqlServer, "Server=A");
221+
cache.GetOrAdd(DatabaseProviderRegistry.SQLite, "Data Source=b.db");
222+
cache.GetOrAdd(DatabaseProviderRegistry.PostgreSql, "Host=c");
223+
224+
var ser = new JsonSerializer<DatabaseConnectionCache>();
225+
var restored = ser.Deserialize(ser.Serialize(cache));
226+
227+
restored.Connections.Count().AssertEqual(3);
228+
229+
var originalPairs = cache.Connections.OrderBy(p => p.Provider).ToArray();
230+
var restoredPairs = restored.Connections.OrderBy(p => p.Provider).ToArray();
231+
232+
for (var i = 0; i < originalPairs.Length; i++)
233+
{
234+
restoredPairs[i].Provider.AssertEqual(originalPairs[i].Provider);
235+
restoredPairs[i].ConnectionString.AssertEqual(originalPairs[i].ConnectionString);
236+
}
237+
}
238+
239+
[TestMethod]
240+
public void SaveLoadDropsEntriesWithEmptyProvider()
241+
{
242+
// Use IPersistable directly to inject an entry with an empty provider, then verify
243+
// that DatabaseConnectionCache.Load filters such invalid entries out.
244+
var pair = new DatabaseConnectionPair
245+
{
246+
Provider = string.Empty,
247+
ConnectionString = "cs",
248+
};
249+
250+
var storage = new SettingsStorage();
251+
storage.SetValue("Connections", new[] { ((IPersistable)pair).Save() });
252+
253+
var cache = new DatabaseConnectionCache();
254+
((IPersistable)cache).Load(storage);
255+
256+
cache.Connections.Count().AssertEqual(0);
257+
}
258+
259+
[TestMethod]
260+
public void PairEqualsSameValues()
261+
{
262+
var a = new DatabaseConnectionPair { Provider = "X", ConnectionString = "Y" };
263+
var b = new DatabaseConnectionPair { Provider = "X", ConnectionString = "Y" };
264+
265+
a.Equals(b).AssertTrue();
266+
b.Equals(a).AssertTrue();
267+
a.GetHashCode().AssertEqual(b.GetHashCode());
268+
}
269+
270+
[TestMethod]
271+
public void PairEqualsIgnoresCase()
272+
{
273+
var a = new DatabaseConnectionPair { Provider = "SqlServer", ConnectionString = "Server=Localhost" };
274+
var b = new DatabaseConnectionPair { Provider = "sqlserver", ConnectionString = "server=localhost" };
275+
276+
a.Equals(b).AssertTrue();
277+
a.GetHashCode().AssertEqual(b.GetHashCode());
278+
}
279+
280+
[TestMethod]
281+
public void PairEqualsDifferentProvider()
282+
{
283+
var a = new DatabaseConnectionPair { Provider = "X", ConnectionString = "cs" };
284+
var b = new DatabaseConnectionPair { Provider = "Y", ConnectionString = "cs" };
285+
286+
a.Equals(b).AssertFalse();
287+
}
288+
289+
[TestMethod]
290+
public void PairEqualsDifferentConnectionString()
291+
{
292+
var a = new DatabaseConnectionPair { Provider = "X", ConnectionString = "cs1" };
293+
var b = new DatabaseConnectionPair { Provider = "X", ConnectionString = "cs2" };
294+
295+
a.Equals(b).AssertFalse();
296+
}
297+
298+
[TestMethod]
299+
public void PairEqualsNullReturnsFalse()
300+
{
301+
var a = new DatabaseConnectionPair { Provider = "X", ConnectionString = "Y" };
302+
a.Equals(null).AssertFalse();
303+
}
304+
305+
[TestMethod]
306+
public void PairEqualsSelfReferenceReturnsTrue()
307+
{
308+
var a = new DatabaseConnectionPair { Provider = "X", ConnectionString = "Y" };
309+
a.Equals(a).AssertTrue();
310+
}
311+
312+
[TestMethod]
313+
public void PairEqualsDifferentTypeReturnsFalse()
314+
{
315+
var a = new DatabaseConnectionPair { Provider = "X", ConnectionString = "Y" };
316+
a.Equals("string").AssertFalse();
317+
}
318+
319+
[TestMethod]
320+
public void PairEqualsBothNullStringsReturnsTrue()
321+
{
322+
var a = new DatabaseConnectionPair();
323+
var b = new DatabaseConnectionPair();
324+
325+
a.Equals(b).AssertTrue();
326+
a.GetHashCode().AssertEqual(b.GetHashCode());
327+
}
328+
329+
[TestMethod]
330+
public void PairTitleFormat()
331+
{
332+
var pair = new DatabaseConnectionPair { Provider = "SqlServer", ConnectionString = "Server=localhost" };
333+
pair.Title.AssertEqual("(SqlServer) Server=localhost");
334+
}
335+
336+
[TestMethod]
337+
public void PairToStringIsTitle()
338+
{
339+
var pair = new DatabaseConnectionPair { Provider = "SQLite", ConnectionString = "Data Source=test.db" };
340+
pair.ToString().AssertEqual(pair.Title);
341+
}
342+
343+
[TestMethod]
344+
public void PairPersistableRoundTrip()
345+
{
346+
var original = new DatabaseConnectionPair
347+
{
348+
Provider = DatabaseProviderRegistry.PostgreSql,
349+
ConnectionString = "Host=h;Port=5432",
350+
};
351+
352+
var storage = new SettingsStorage();
353+
((IPersistable)original).Save(storage);
354+
355+
var restored = new DatabaseConnectionPair();
356+
((IPersistable)restored).Load(storage);
357+
358+
restored.Provider.AssertEqual(original.Provider);
359+
restored.ConnectionString.AssertEqual(original.ConnectionString);
360+
}
361+
362+
[TestMethod]
363+
public void PairTitleNotifiesOnProviderChange()
364+
{
365+
var pair = new DatabaseConnectionPair { Provider = "A", ConnectionString = "cs" };
366+
var notifications = new List<string>();
367+
pair.PropertyChanged += (_, e) => notifications.Add(e.PropertyName);
368+
369+
pair.Provider = "B";
370+
371+
notifications.Contains(nameof(DatabaseConnectionPair.Title)).AssertTrue();
372+
}
373+
374+
[TestMethod]
375+
public void PairTitleNotifiesOnConnectionStringChange()
376+
{
377+
var pair = new DatabaseConnectionPair { Provider = "A", ConnectionString = "cs1" };
378+
var notifications = new List<string>();
379+
pair.PropertyChanged += (_, e) => notifications.Add(e.PropertyName);
380+
381+
pair.ConnectionString = "cs2";
382+
383+
notifications.Contains(nameof(DatabaseConnectionPair.Title)).AssertTrue();
384+
}
40385
}

0 commit comments

Comments
 (0)