DateTime unit test
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
unit Test.Myc.Ast.RTL.DateTime;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
DUnitX.TestFramework,
|
||||
System.SysUtils,
|
||||
System.DateUtils,
|
||||
System.Math,
|
||||
Myc.Ast.Environment,
|
||||
Myc.Ast.Script,
|
||||
Myc.Data.Value,
|
||||
Myc.Data.Scalar;
|
||||
|
||||
type
|
||||
[TestFixture]
|
||||
[IgnoreMemoryLeaks]
|
||||
TTestRtlDateTime = class
|
||||
private
|
||||
FEnv: TAstEnvironment;
|
||||
public
|
||||
[Setup]
|
||||
procedure Setup;
|
||||
[Teardown]
|
||||
procedure Teardown;
|
||||
|
||||
[Test]
|
||||
procedure Test_Constructor_FixedDate;
|
||||
|
||||
[Test]
|
||||
procedure Test_Constructor_Now;
|
||||
|
||||
[Test]
|
||||
[TestCase('Later', '2025,1,1,2024,1,1,True')]
|
||||
[TestCase('Earlier', '2020,1,1,2021,1,1,False')]
|
||||
procedure Test_GreaterThan(Y1, M1, D1, Y2, M2, D2: Integer; ExpectTrue: Boolean);
|
||||
|
||||
[Test]
|
||||
procedure Test_Equality;
|
||||
|
||||
[Test]
|
||||
procedure Test_DateTime_Is_Truthy;
|
||||
|
||||
[Test]
|
||||
procedure Test_Round_DateTime;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TTestRtlDateTime.Setup;
|
||||
begin
|
||||
// Creates a fresh environment with all RTL functions registered
|
||||
// (including Date, Now, True, False)
|
||||
FEnv := TAstEnvironment.Construct(nil);
|
||||
end;
|
||||
|
||||
procedure TTestRtlDateTime.Teardown;
|
||||
begin
|
||||
// Environment is a record (interface wrapper), automatic cleanup
|
||||
end;
|
||||
|
||||
procedure TTestRtlDateTime.Test_Constructor_FixedDate;
|
||||
var
|
||||
Res: TDataValue;
|
||||
Expected: TDateTime;
|
||||
begin
|
||||
// Act
|
||||
Res := FEnv.Run(TAstScript.Parse('(Date 2025 11 24)'));
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(TDataValueKind.vkScalar, Res.Kind, 'Result should be scalar');
|
||||
Assert.AreEqual(TScalar.TKind.DateTime, Res.AsScalar.Kind, 'Scalar kind should be DateTime');
|
||||
|
||||
Expected := EncodeDate(2025, 11, 24);
|
||||
Assert.AreEqual(Expected, Res.AsScalar.Value.AsDouble, 0.0001, 'Date value mismatch');
|
||||
end;
|
||||
|
||||
procedure TTestRtlDateTime.Test_Constructor_Now;
|
||||
var
|
||||
Res: TDataValue;
|
||||
Before, After: TDateTime;
|
||||
begin
|
||||
Before := System.SysUtils.Now;
|
||||
// Allow small window for execution time
|
||||
Sleep(1);
|
||||
|
||||
// Act
|
||||
Res := FEnv.Run(TAstScript.Parse('(Now)'));
|
||||
|
||||
After := System.SysUtils.Now;
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(TScalar.TKind.DateTime, Res.AsScalar.Kind);
|
||||
|
||||
// Check if result is within the time window
|
||||
Assert.IsTrue(Res.AsScalar.Value.AsDouble >= Before);
|
||||
Assert.IsTrue(Res.AsScalar.Value.AsDouble <= After);
|
||||
end;
|
||||
|
||||
procedure TTestRtlDateTime.Test_GreaterThan(Y1, M1, D1, Y2, M2, D2: Integer; ExpectTrue: Boolean);
|
||||
var
|
||||
Script: string;
|
||||
Res: TDataValue;
|
||||
begin
|
||||
// (> (Date y1 m1 d1) (Date y2 m2 d2))
|
||||
Script := Format('(> (Date %d %d %d) (Date %d %d %d))', [Y1, M1, D1, Y2, M2, D2]);
|
||||
|
||||
Res := FEnv.Run(TAstScript.Parse(Script));
|
||||
|
||||
Assert.AreEqual(TScalar.TKind.Boolean, Res.AsScalar.Kind);
|
||||
|
||||
if ExpectTrue then
|
||||
Assert.AreEqual(Int64(1), Res.AsScalar.Value.AsInt64, 'Expected True')
|
||||
else
|
||||
Assert.AreEqual(Int64(0), Res.AsScalar.Value.AsInt64, 'Expected False');
|
||||
end;
|
||||
|
||||
procedure TTestRtlDateTime.Test_Equality;
|
||||
var
|
||||
Res: TDataValue;
|
||||
begin
|
||||
// (= (Date 2023 10 10) (Date 2023 10 10))
|
||||
Res := FEnv.Run(TAstScript.Parse('(= (Date 2023 10 10) (Date 2023 10 10))'));
|
||||
|
||||
Assert.AreEqual(TScalar.TKind.Boolean, Res.AsScalar.Kind);
|
||||
Assert.AreEqual(Int64(1), Res.AsScalar.Value.AsInt64);
|
||||
end;
|
||||
|
||||
procedure TTestRtlDateTime.Test_DateTime_Is_Truthy;
|
||||
var
|
||||
Res: TDataValue;
|
||||
begin
|
||||
// (if (Date 2023 1 1) "yes" "no")
|
||||
// Checks if IsTruthy correctly handles TKind.DateTime
|
||||
Res := FEnv.Run(TAstScript.Parse('(if (Date 2023 1 1) "yes" "no")'));
|
||||
|
||||
Assert.AreEqual(TDataValueKind.vkText, Res.Kind);
|
||||
Assert.AreEqual('yes', Res.AsText);
|
||||
end;
|
||||
|
||||
procedure TTestRtlDateTime.Test_Round_DateTime;
|
||||
var
|
||||
Res: TDataValue;
|
||||
InputDate: TDateTime;
|
||||
Expected: Int64;
|
||||
begin
|
||||
// Ensure RTL Round handles DateTime as float
|
||||
// (Round (Date 2023 11 24))
|
||||
// Date creates a TDateTime (Double) with 0.0 time fraction, so Round should return the truncation.
|
||||
|
||||
InputDate := EncodeDate(2023, 11, 24);
|
||||
Expected := System.Round(InputDate);
|
||||
|
||||
Res := FEnv.Run(TAstScript.Parse('(Round (Date 2023 11 24))'));
|
||||
|
||||
Assert.AreEqual(TScalar.TKind.Ordinal, Res.AsScalar.Kind);
|
||||
Assert.AreEqual(Expected, Res.AsScalar.Value.AsInt64);
|
||||
end;
|
||||
|
||||
end.
|
||||
+2
-1
@@ -30,7 +30,8 @@ uses
|
||||
Test.Myc.Ast.Scope in 'AST\Test.Myc.Ast.Scope.pas',
|
||||
Test.Myc.Ast.RTL in 'AST\Test.Myc.Ast.RTL.pas',
|
||||
Test.Myc.Ast.Script in 'AST\Test.Myc.Ast.Script.pas',
|
||||
Test.Myc.Ast.Compiler.Macros in 'AST\Test.Myc.Ast.Compiler.Macros.pas';
|
||||
Test.Myc.Ast.Compiler.Macros in 'AST\Test.Myc.Ast.Compiler.Macros.pas',
|
||||
Test.Myc.Ast.RTL.DateTime in 'AST\Test.Myc.Ast.RTL.DateTime.pas';
|
||||
|
||||
{ keep comment here to protect the following conditional from being removed by the IDE when adding a unit }
|
||||
{$IFNDEF TESTINSIGHT}
|
||||
|
||||
@@ -132,6 +132,7 @@ $(PreBuildEvent)]]></PreBuildEvent>
|
||||
<DCCReference Include="AST\Test.Myc.Ast.RTL.pas"/>
|
||||
<DCCReference Include="AST\Test.Myc.Ast.Script.pas"/>
|
||||
<DCCReference Include="AST\Test.Myc.Ast.Compiler.Macros.pas"/>
|
||||
<DCCReference Include="AST\Test.Myc.Ast.RTL.DateTime.pas"/>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
</BuildConfiguration>
|
||||
|
||||
Reference in New Issue
Block a user