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; // 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(srcRecord); // Assert: Retrieve each value and check for correctness Assert.AreEqual(srcRecord.MyInt64, dataRecord.GetValue('MyInt64'), 'Int64 value mismatch'); Assert.AreEqual(srcRecord.MyInteger, dataRecord.GetValue('MyInteger'), 'Integer value mismatch'); Assert.AreEqual(srcRecord.MyString, dataRecord.GetValue('MyString'), 'String value mismatch'); Assert.AreEqual(srcRecord.MyTimestamp, dataRecord.GetValue('MyTimestamp'), 'TDateTime value mismatch'); // Assert: Check float values with a tolerance for precision differences Assert.AreEqual(srcRecord.MySingle, dataRecord.GetValue('MySingle'), 1e-6, 'Single value mismatch'); Assert.AreEqual(srcRecord.MyDouble, dataRecord.GetValue('MyDouble'), 1e-9, 'Double value mismatch'); // Assert: Test type promotion (reading an Integer as Int64) Assert.IsTrue(srcRecord.MyInteger = dataRecord.GetValue('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; // 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('MyInteger', testInt); dataRecord.SetValue('MyInt64', testInt64); dataRecord.SetValue('MySingle', testSingle); dataRecord.SetValue('MyDouble', testDouble); dataRecord.SetValue('MyString', testString); dataRecord.SetValue('MyTimestamp', testTimestamp); // Assert: Retrieve the values and check if they match what was set Assert.AreEqual(testInt, dataRecord.GetValue('MyInteger'), 'SetValue failed for Integer'); Assert.AreEqual(testInt64, dataRecord.GetValue('MyInt64'), 'SetValue failed for Int64'); Assert.AreEqual(testString, dataRecord.GetValue('MyString'), 'SetValue failed for String'); Assert.AreEqual(testTimestamp, dataRecord.GetValue('MyTimestamp'), 'SetValue failed for TDateTime'); Assert.AreEqual(testSingle, dataRecord.GetValue('MySingle'), 1e-6, 'SetValue failed for Single'); Assert.AreEqual(testDouble, dataRecord.GetValue('MyDouble'), 1e-9, 'SetValue failed for Double'); end; initialization TDUnitX.RegisterTestFixture(TTestDataRecord); end.