Files
MycLib/Test/TestDataRecord.pas
T
2025-07-22 01:13:01 +02:00

149 lines
5.7 KiB
ObjectPascal

unit TestDataRecord;
interface
uses
DunitX.TestFramework,
System.SysUtils,
System.DateUtils,
Myc.DataRecord;
type
// A record that contains all supported data types for testing
TMyTestRecord = record
MyInteger: Integer;
MyInt64: Int64;
MySingle: Single;
MyDouble: Double;
MyString: string;
MyTimestamp: TDateTime;
end;
[TestFixture]
TTestDataRecord = class(TObject)
public
[Test]
procedure TestLayoutCreation;
[Test]
procedure TestCreateFromInstanceAndGetValue;
[Test]
procedure TestSetValueAndGetValue;
end;
implementation
uses
System.Rtti;
{ TTestDataRecord }
procedure TTestDataRecord.TestLayoutCreation;
var
layout: TDataRecord.TRecordLayout;
idx: Integer;
expectedSize: Integer;
begin
// Test: Create layout from a record type
layout := TDataRecord.TRecordLayout.CreateFrom<TMyTestRecord>;
// Assert: Check field count
Assert.IsTrue(Length(layout.Fields) = 6, 'Layout should have 6 fields');
// Assert: Check specific fields for correct type mapping
idx := layout.IndexOf('MyInteger');
Assert.IsTrue(idx > -1, 'Field MyInteger not found');
Assert.AreEqual(TDataFieldType.dfInteger, layout.Fields[idx].FieldType, 'MyInteger should be mapped to dfInteger');
idx := layout.IndexOf('MyString');
Assert.IsTrue(idx > -1, 'Field MyString not found');
Assert.AreEqual(TDataFieldType.dfString, layout.Fields[idx].FieldType, 'MyString should be mapped to dfString');
idx := layout.IndexOf('MySingle');
Assert.IsTrue(idx > -1, 'Field MySingle not found');
Assert.AreEqual(TDataFieldType.dfFloat, layout.Fields[idx].FieldType, 'MySingle should be mapped to dfFloat');
idx := layout.IndexOf('MyTimestamp');
Assert.IsTrue(idx > -1, 'Field MyTimestamp not found');
Assert.AreEqual(TDataFieldType.dfTimestamp, layout.Fields[idx].FieldType, 'MyTimestamp should be mapped to dfTimestamp');
// Assert: Check total buffer size (6 fields * 8 bytes each on x64 due to type promotion and alignment)
expectedSize := (sizeof(Int64) * 2) + (sizeof(Double) * 2) + sizeof(String) + sizeof(TDateTime);
Assert.AreEqual(expectedSize, layout.GetBufferSize, 'Buffer size calculation is incorrect');
end;
procedure TTestDataRecord.TestCreateFromInstanceAndGetValue;
var
srcRecord: TMyTestRecord;
dataRecord: TDataRecord;
begin
// Setup: Create and populate a source record
srcRecord.MyInteger := 12345;
srcRecord.MyInt64 := 9876543210;
srcRecord.MySingle := 123.456;
srcRecord.MyDouble := 789.012345;
srcRecord.MyString := 'Hello Delphi!';
srcRecord.MyTimestamp := EncodeDateTime(2024, 7, 19, 10, 30, 0, 0);
// Test: Create a TDataRecord from the source record instance
dataRecord := TDataRecord.CreateFrom<TMyTestRecord>(srcRecord);
// Assert: Retrieve each value and check for correctness
Assert.AreEqual(srcRecord.MyInt64, dataRecord.GetValue<Int64>('MyInt64'), 'Int64 value mismatch');
Assert.AreEqual(srcRecord.MyInteger, dataRecord.GetValue<Integer>('MyInteger'), 'Integer value mismatch');
Assert.AreEqual(srcRecord.MyString, dataRecord.GetValue<string>('MyString'), 'String value mismatch');
Assert.AreEqual(srcRecord.MyTimestamp, dataRecord.GetValue<TDateTime>('MyTimestamp'), 'TDateTime value mismatch');
// Assert: Check float values with a tolerance for precision differences
Assert.AreEqual(srcRecord.MySingle, dataRecord.GetValue<Single>('MySingle'), 1e-6, 'Single value mismatch');
Assert.AreEqual(srcRecord.MyDouble, dataRecord.GetValue<Double>('MyDouble'), 1e-9, 'Double value mismatch');
// Assert: Test type promotion (reading an Integer as Int64)
Assert.IsTrue(srcRecord.MyInteger = dataRecord.GetValue<Int64>('MyInteger'), 'Integer to Int64 promotion failed');
end;
procedure TTestDataRecord.TestSetValueAndGetValue;
var
dataRecord: TDataRecord;
testInt: Integer;
testInt64: Int64;
testSingle: Single;
testDouble: Double;
testString: string;
testTimestamp: TDateTime;
begin
// Setup: Create an empty TDataRecord with the layout of TMyTestRecord
dataRecord := TDataRecord.CreateFrom<TMyTestRecord>;
// Setup: Define test values
testInt := 54321;
testInt64 := 12345678901;
testSingle := 987.654;
testDouble := 543.210987;
testString := 'Testing SetValue';
testTimestamp := Now;
// Test: Set values for each field by name
dataRecord.SetValue<Integer>('MyInteger', testInt);
dataRecord.SetValue<Int64>('MyInt64', testInt64);
dataRecord.SetValue<Single>('MySingle', testSingle);
dataRecord.SetValue<Double>('MyDouble', testDouble);
dataRecord.SetValue<string>('MyString', testString);
dataRecord.SetValue<TDateTime>('MyTimestamp', testTimestamp);
// Assert: Retrieve the values and check if they match what was set
Assert.AreEqual(testInt, dataRecord.GetValue<Integer>('MyInteger'), 'SetValue failed for Integer');
Assert.AreEqual(testInt64, dataRecord.GetValue<Int64>('MyInt64'), 'SetValue failed for Int64');
Assert.AreEqual(testString, dataRecord.GetValue<string>('MyString'), 'SetValue failed for String');
Assert.AreEqual(testTimestamp, dataRecord.GetValue<TDateTime>('MyTimestamp'), 'SetValue failed for TDateTime');
Assert.AreEqual(testSingle, dataRecord.GetValue<Single>('MySingle'), 1e-6, 'SetValue failed for Single');
Assert.AreEqual(testDouble, dataRecord.GetValue<Double>('MyDouble'), 1e-9, 'SetValue failed for Double');
end;
initialization
TDUnitX.RegisterTestFixture(TTestDataRecord);
end.