Skip to content

Commit 1bfa978

Browse files
NH-3919 - More date types tests, and refactoring of them.
1 parent 2f88b5a commit 1bfa978

32 files changed

+1267
-1256
lines changed
Lines changed: 385 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,385 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System;
12+
using System.Collections.Generic;
13+
using System.Data;
14+
using System.Data.Common;
15+
using System.Linq;
16+
using System.Reflection;
17+
using NHibernate.Cfg;
18+
using NHibernate.Driver;
19+
using NHibernate.Engine;
20+
using NHibernate.SqlCommand;
21+
using NHibernate.SqlTypes;
22+
using NHibernate.Tool.hbm2ddl;
23+
using NHibernate.Type;
24+
using NHibernate.Util;
25+
using NUnit.Framework;
26+
27+
namespace NHibernate.Test.TypesTest
28+
{
29+
using System.Threading.Tasks;
30+
using System.Threading;
31+
[TestFixture]
32+
public abstract class AbstractDateTimeTypeFixtureAsync : TypeFixtureBase
33+
{
34+
protected abstract AbstractDateTimeType Type { get; }
35+
protected virtual bool RevisionCheck => true;
36+
37+
protected const int DateId = 1;
38+
protected const int AdditionalDateId = 2;
39+
40+
protected override void Configure(Configuration configuration)
41+
{
42+
base.Configure(configuration);
43+
44+
var driverClass = ReflectHelper.ClassForName(configuration.GetProperty(Cfg.Environment.ConnectionDriver));
45+
ClientDriverWithParamsStats.DriverClass = driverClass;
46+
47+
configuration.SetProperty(
48+
Cfg.Environment.ConnectionDriver,
49+
typeof(ClientDriverWithParamsStats).AssemblyQualifiedName);
50+
}
51+
52+
protected override void OnSetUp()
53+
{
54+
base.OnSetUp();
55+
56+
using (var s = OpenSession())
57+
using (var t = s.BeginTransaction())
58+
{
59+
var d = new DateTimeClass
60+
{
61+
Id = DateId,
62+
Value = Now
63+
};
64+
s.Save(d);
65+
t.Commit();
66+
}
67+
}
68+
69+
protected override void OnTearDown()
70+
{
71+
base.OnTearDown();
72+
73+
using (var s = OpenSession())
74+
using (var t = s.BeginTransaction())
75+
{
76+
s.CreateQuery("delete from DateTimeClass").ExecuteUpdate();
77+
t.Commit();
78+
}
79+
}
80+
81+
protected override void DropSchema()
82+
{
83+
(Sfi.ConnectionProvider.Driver as ClientDriverWithParamsStats)?.CleanUp();
84+
base.DropSchema();
85+
}
86+
87+
[Test]
88+
public async Task NextAsync()
89+
{
90+
var current = DateTime.Parse("2004-01-01");
91+
var next = await (Type.NextAsync(current, null, CancellationToken.None));
92+
93+
Assert.That(next, Is.TypeOf<DateTime>(), "next should be DateTime");
94+
Assert.That(next, Is.GreaterThan(current), "next should be greater than current");
95+
}
96+
97+
[Test]
98+
public async Task SeedAsync()
99+
{
100+
Assert.That(await (Type.SeedAsync(null, CancellationToken.None)), Is.TypeOf<DateTime>(), "seed should be DateTime");
101+
}
102+
103+
[Test]
104+
[TestCase(DateTimeKind.Unspecified)]
105+
[TestCase(DateTimeKind.Local)]
106+
[TestCase(DateTimeKind.Utc)]
107+
public virtual async Task ReadWriteAsync(DateTimeKind kind)
108+
{
109+
var entity = new DateTimeClass
110+
{
111+
Id = AdditionalDateId,
112+
Value = GetTestDate(kind)
113+
};
114+
115+
DateTime beforeNow, afterNow;
116+
117+
// Save
118+
using (var s = OpenSession())
119+
using (var t = s.BeginTransaction())
120+
{
121+
// Account db accuracy
122+
beforeNow = Now.AddTicks(-DateAccuracyInTicks);
123+
await (s.SaveAsync(entity));
124+
await (t.CommitAsync());
125+
afterNow = Now.AddTicks(DateAccuracyInTicks);
126+
}
127+
128+
var typeKind = GetTypeKind();
129+
if (RevisionCheck)
130+
{
131+
Assert.That(entity.Revision, Is.GreaterThan(beforeNow).And.LessThan(afterNow), "Revision not correctly seeded.");
132+
if (typeKind != DateTimeKind.Unspecified)
133+
Assert.That(entity.Revision.Kind, Is.EqualTo(typeKind), "Revision kind not correctly seeded.");
134+
Assert.That(entity.NullableValue, Is.Null, "NullableValue unexpectedly seeded.");
135+
}
136+
137+
// Retrieve, compare then update
138+
DateTimeClass retrieved;
139+
using (var s = OpenSession())
140+
using (var t = s.BeginTransaction())
141+
{
142+
retrieved = await (s.GetAsync<DateTimeClass>(AdditionalDateId));
143+
144+
Assert.That(retrieved, Is.Not.Null, "Entity not saved or cannot be retrieved by its key.");
145+
Assert.That(retrieved.Value, Is.EqualTo(entity.Value), "Value should be the same.");
146+
if (RevisionCheck)
147+
Assert.That(retrieved.Revision, Is.EqualTo(entity.Revision), "Revision should be the same.");
148+
Assert.That(retrieved.NullableValue, Is.EqualTo(entity.NullableValue), "NullableValue should be the same.");
149+
if (typeKind != DateTimeKind.Unspecified)
150+
{
151+
Assert.That(retrieved.Value.Kind, Is.EqualTo(typeKind), "Value kind not correctly retrieved.");
152+
if (RevisionCheck)
153+
Assert.That(retrieved.Revision.Kind, Is.EqualTo(typeKind), "Revision kind not correctly retrieved.");
154+
}
155+
156+
retrieved.NullableValue = GetTestDate(kind);
157+
retrieved.Value = GetTestDate(kind).AddMonths(-1);
158+
159+
beforeNow = Now.AddTicks(-DateAccuracyInTicks);
160+
await (t.CommitAsync());
161+
afterNow = Now.AddTicks(DateAccuracyInTicks);
162+
}
163+
164+
if (RevisionCheck)
165+
{
166+
Assert.That(
167+
retrieved.Revision,
168+
Is.GreaterThan(beforeNow).And.LessThan(afterNow).And.GreaterThanOrEqualTo(entity.Revision),
169+
"Revision not correctly incremented.");
170+
if (typeKind != DateTimeKind.Unspecified)
171+
Assert.That(retrieved.Revision.Kind, Is.EqualTo(typeKind), "Revision kind incorrectly changed.");
172+
}
173+
174+
// Retrieve and compare again
175+
using (var s = OpenSession())
176+
using (var t = s.BeginTransaction())
177+
{
178+
var retrievedAgain = await (s.GetAsync<DateTimeClass>(AdditionalDateId));
179+
180+
Assert.That(retrievedAgain, Is.Not.Null, "Entity deleted or cannot be retrieved again by its key.");
181+
Assert.That(retrievedAgain.Value, Is.EqualTo(retrieved.Value), "Value should be the same again.");
182+
if (RevisionCheck)
183+
Assert.That(retrievedAgain.Revision, Is.EqualTo(retrieved.Revision), "Revision should be the same again.");
184+
Assert.That(
185+
retrievedAgain.NullableValue,
186+
Is.EqualTo(retrieved.NullableValue),
187+
"NullableValue should be the same again.");
188+
if (typeKind != DateTimeKind.Unspecified)
189+
{
190+
Assert.That(retrievedAgain.Value.Kind, Is.EqualTo(typeKind), "Value kind not correctly retrieved again.");
191+
if (RevisionCheck)
192+
Assert.That(retrievedAgain.Revision.Kind, Is.EqualTo(typeKind), "Revision kind not correctly retrieved again.");
193+
Assert.That(
194+
retrievedAgain.NullableValue.Value.Kind,
195+
Is.EqualTo(typeKind),
196+
"NullableValue kind not correctly retrieved again.");
197+
}
198+
await (t.CommitAsync());
199+
}
200+
}
201+
202+
[Test]
203+
public Task DbHasExpectedTypeAsync()
204+
{
205+
try
206+
{
207+
var validator = new SchemaValidator(cfg);
208+
return validator.ValidateAsync();
209+
}
210+
catch (Exception ex)
211+
{
212+
return Task.FromException<object>(ex);
213+
}
214+
}
215+
216+
[Test]
217+
public async Task SaveUseExpectedSqlTypeAsync()
218+
{
219+
var driver = (ClientDriverWithParamsStats) Sfi.ConnectionProvider.Driver;
220+
221+
using (var s = OpenSession())
222+
using (var t = s.BeginTransaction())
223+
{
224+
var d = new DateTimeClass
225+
{
226+
Id = 2,
227+
Value = Now,
228+
NullableValue = Now
229+
};
230+
driver.ClearStats();
231+
await (s.SaveAsync(d));
232+
await (t.CommitAsync());
233+
}
234+
235+
// 2 properties + revision
236+
AssertSqlType(driver, 3);
237+
}
238+
239+
[Test]
240+
public async Task UpdateUseExpectedSqlTypeAsync()
241+
{
242+
var driver = (ClientDriverWithParamsStats) Sfi.ConnectionProvider.Driver;
243+
244+
using (var s = OpenSession())
245+
using (var t = s.BeginTransaction())
246+
{
247+
var d = await (s.GetAsync<DateTimeClass>(DateId));
248+
d.Value = Now;
249+
d.NullableValue = Now;
250+
driver.ClearStats();
251+
await (t.CommitAsync());
252+
}
253+
254+
// 2 properties + revision x 2 (check + update)
255+
AssertSqlType(driver, 4);
256+
}
257+
258+
[Test]
259+
public virtual async Task QueryUseExpectedSqlTypeAsync()
260+
{
261+
if (!TestDialect.SupportsNonDataBoundCondition)
262+
Assert.Ignore("Dialect does not support the test query");
263+
264+
var driver = (ClientDriverWithParamsStats) Sfi.ConnectionProvider.Driver;
265+
266+
using (var s = OpenSession())
267+
using (var t = s.BeginTransaction())
268+
{
269+
var q = s
270+
.CreateQuery(
271+
"from DateTimeClass d where d.Value = :value and " +
272+
"d.NullableValue = :nullableValue and " +
273+
"d.Revision = :revision and " +
274+
":other1 = :other2")
275+
.SetDateTime("value", Now)
276+
.SetDateTime("nullableValue", Now)
277+
.SetDateTime("revision", Now)
278+
.SetDateTime("other1", Now)
279+
.SetDateTime("other2", Now);
280+
driver.ClearStats();
281+
await (q.ListAsync<DateTimeClass>());
282+
await (t.CommitAsync());
283+
}
284+
285+
AssertSqlType(driver, 5);
286+
}
287+
288+
private void AssertSqlType(ClientDriverWithParamsStats driver, int expectedCount)
289+
{
290+
if (Type.SqlTypes(Sfi).Any(t => Equals(t, SqlTypeFactory.DateTime2)))
291+
{
292+
Assert.That(
293+
driver.GetCount(SqlTypeFactory.DateTime),
294+
Is.EqualTo(0),
295+
"Found unexpected SqlTypeFactory.DateTime usages.");
296+
Assert.That(
297+
driver.GetCount(SqlTypeFactory.DateTime2),
298+
Is.EqualTo(expectedCount),
299+
"Unexpected SqlTypeFactory.DateTime2 usage count.");
300+
Assert.That(driver.GetCount(DbType.DateTime), Is.EqualTo(0), "Found unexpected DbType.DateTime usages.");
301+
Assert.That(
302+
driver.GetCount(DbType.DateTime2),
303+
Is.EqualTo(expectedCount),
304+
"Unexpected DbType.DateTime2 usage count.");
305+
}
306+
else if (Type.SqlTypes(Sfi).Any(t => Equals(t, SqlTypeFactory.DateTime)))
307+
{
308+
Assert.That(
309+
driver.GetCount(SqlTypeFactory.DateTime2),
310+
Is.EqualTo(0),
311+
"Found unexpected SqlTypeFactory.DateTime2 usages.");
312+
Assert.That(
313+
driver.GetCount(SqlTypeFactory.DateTime),
314+
Is.EqualTo(expectedCount),
315+
"Unexpected SqlTypeFactory.DateTime usage count.");
316+
Assert.That(driver.GetCount(DbType.DateTime2), Is.EqualTo(0), "Found unexpected DbType.DateTime2 usages.");
317+
Assert.That(driver.GetCount(DbType.DateTime), Is.EqualTo(expectedCount), "Unexpected DbType.DateTime usage count.");
318+
}
319+
else if (Type.SqlTypes(Sfi).Any(t => Equals(t, SqlTypeFactory.Date)))
320+
{
321+
Assert.That(
322+
driver.GetCount(SqlTypeFactory.DateTime),
323+
Is.EqualTo(0),
324+
"Found unexpected SqlTypeFactory.DateTime usages.");
325+
Assert.That(
326+
driver.GetCount(SqlTypeFactory.Date),
327+
Is.EqualTo(expectedCount),
328+
"Unexpected SqlTypeFactory.Date usage count.");
329+
Assert.That(driver.GetCount(DbType.DateTime), Is.EqualTo(0), "Found unexpected DbType.DateTime usages.");
330+
Assert.That(driver.GetCount(DbType.Date), Is.EqualTo(expectedCount), "Unexpected DbType.Date usage count.");
331+
}
332+
}
333+
334+
protected virtual long DateAccuracyInTicks => Dialect.TimestampResolutionInTicks;
335+
336+
protected DateTime Now => GetTypeKind() == DateTimeKind.Utc ? DateTime.UtcNow : DateTime.Now;
337+
338+
protected virtual DateTime GetTestDate(DateTimeKind kind)
339+
{
340+
return RoundForDialect(
341+
kind == DateTimeKind.Utc ? DateTime.UtcNow : DateTime.SpecifyKind(DateTime.Now, kind))
342+
// Take another date than now for checking the value do not get overridden by seeding.
343+
.AddDays(1);
344+
}
345+
346+
/// <summary>
347+
/// Return a date time still considered equal but as different as possible.
348+
/// </summary>
349+
/// <param name="original">The originale date time.</param>
350+
/// <returns>An equal date time.</returns>
351+
protected virtual DateTime GetSameDate(DateTime original)
352+
{
353+
if (GetTypeKind() != DateTimeKind.Unspecified)
354+
return new DateTime(original.Ticks, original.Kind);
355+
356+
switch (original.Kind)
357+
{
358+
case DateTimeKind.Local:
359+
return DateTime.SpecifyKind(original, DateTimeKind.Unspecified);
360+
case DateTimeKind.Unspecified:
361+
return DateTime.SpecifyKind(original, DateTimeKind.Utc);
362+
default:
363+
return DateTime.SpecifyKind(original, DateTimeKind.Local);
364+
}
365+
}
366+
367+
/// <summary>
368+
/// Return a different date time but as few different as possible.
369+
/// </summary>
370+
/// <param name="original">The originale date time.</param>
371+
/// <returns>An inequal date time.</returns>
372+
protected virtual DateTime GetDifferentDate(DateTime original)
373+
{
374+
return original.AddTicks(DateAccuracyInTicks);
375+
}
376+
377+
private static readonly PropertyInfo _kindProperty =
378+
typeof(AbstractDateTimeType).GetProperty("Kind", BindingFlags.Instance | BindingFlags.NonPublic);
379+
380+
protected DateTimeKind GetTypeKind()
381+
{
382+
return (DateTimeKind) _kindProperty.GetValue(Type);
383+
}
384+
}
385+
}

0 commit comments

Comments
 (0)