Implemented TLazy + Tests
This commit is contained in:
@@ -0,0 +1,456 @@
|
||||
unit Myc.Test.Core.Lazy;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
DUnitX.TestFramework,
|
||||
Myc.Signals, // For IMycState, TState, IMycDirty
|
||||
Myc.Lazy, // For IMycLazy<T>
|
||||
Myc.Core.Lazy; // Unit to be tested
|
||||
|
||||
type
|
||||
[TestFixture]
|
||||
TTestMycCoreLazy = class(TObject)
|
||||
private
|
||||
procedure Helper_ConsumeInitialPop(const ALazy: IMycLazy<Integer>; InitialExpectedValue: Integer); overload;
|
||||
procedure Helper_ConsumeInitialPop(const ALazy: IMycLazy<string>; const InitialExpectedValue: string); overload;
|
||||
public
|
||||
[Setup]
|
||||
procedure Setup;
|
||||
[TearDown]
|
||||
procedure TearDown;
|
||||
|
||||
// Tests for TMycNullLazy<T>
|
||||
[Test]
|
||||
procedure TestNullLazy_GetChanged_IsAlwaysNullState;
|
||||
[Test]
|
||||
procedure TestNullLazy_Pop_ReturnsDefaultIntegerAndTrue;
|
||||
[Test]
|
||||
procedure TestNullLazy_Pop_ReturnsDefaultStringAndTrue;
|
||||
[Test]
|
||||
procedure TestNullLazy_Pop_ReturnsDefaultInterfaceAndTrue;
|
||||
|
||||
// Tests for TMycFuncLazy<T> reflecting "IsSet is true by design after creation"
|
||||
[Test]
|
||||
procedure TestFuncLazy_GetChanged_IsAlwaysTrueAfterCreation;
|
||||
[Test]
|
||||
procedure TestFuncLazy_FirstPop_AlwaysEvaluatesAndResetsChanged;
|
||||
[Test]
|
||||
procedure TestFuncLazy_Pop_WhenProcIsNull_FirstPopReturnsTrueAndValueUnchanged_ResetsChanged;
|
||||
|
||||
// Tests for behavior after the initial "changed" state is consumed
|
||||
[Test]
|
||||
procedure TestFuncLazy_AfterFirstPop_IfNoSourceChange_GetChangedIsFalse;
|
||||
[Test]
|
||||
procedure TestFuncLazy_AfterFirstPop_IfNoSourceChange_PopReturnsFalse_ValueUndefined;
|
||||
[Test]
|
||||
procedure TestFuncLazy_AfterSourceChange_GetChanged_IsSet;
|
||||
[Test]
|
||||
procedure TestFuncLazy_AfterSourceChange_Pop_ReturnsTrueAndProcResult_ResetsChanged;
|
||||
|
||||
[Test]
|
||||
procedure TestFuncLazy_Pop_Twice_SourceUnchanged_SecondPopReturnsFalse_ValueUndefined;
|
||||
// This test is now significantly changed to reflect TMycDirty's notification behavior
|
||||
[Test]
|
||||
procedure TestFuncLazy_SourceInteraction_NotifyOnSetSourceDoesNotRetriggerLazy;
|
||||
[Test]
|
||||
procedure TestFuncLazy_Destroy_UnsubscribesFromSource;
|
||||
[Test]
|
||||
procedure TestFuncLazy_SourceIsInitiallySet_PopBehavesCorrectly;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
System.Rtti,
|
||||
Myc.Core.Signals;
|
||||
|
||||
{ TTestMycCoreLazy Helper Methods }
|
||||
|
||||
procedure TTestMycCoreLazy.Helper_ConsumeInitialPop(const ALazy: IMycLazy<Integer>; InitialExpectedValue: Integer);
|
||||
var
|
||||
tempValue: Integer;
|
||||
popResult: Boolean;
|
||||
begin
|
||||
Assert.IsTrue(ALazy.GetChanged.IsSet, 'Changed.IsSet should be true before consuming initial pop');
|
||||
popResult := ALazy.Pop(tempValue);
|
||||
Assert.IsTrue(popResult, 'Consuming initial Pop should return true');
|
||||
Assert.AreEqual(InitialExpectedValue, tempValue, 'Value from initial Pop is unexpected');
|
||||
Assert.IsFalse(ALazy.GetChanged.IsSet, 'Changed.IsSet should be false after consuming initial pop');
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.Helper_ConsumeInitialPop(const ALazy: IMycLazy<string>; const InitialExpectedValue: string);
|
||||
var
|
||||
tempValue: string;
|
||||
popResult: Boolean;
|
||||
begin
|
||||
Assert.IsTrue(ALazy.GetChanged.IsSet, 'Changed.IsSet should be true before consuming initial pop');
|
||||
popResult := ALazy.Pop(tempValue);
|
||||
Assert.IsTrue(popResult, 'Consuming initial Pop should return true');
|
||||
Assert.AreEqual(InitialExpectedValue, tempValue, 'Value from initial Pop is unexpected');
|
||||
Assert.IsFalse(ALazy.GetChanged.IsSet, 'Changed.IsSet should be false after consuming initial pop');
|
||||
end;
|
||||
|
||||
{ TTestMycCoreLazy Test Methods }
|
||||
|
||||
procedure TTestMycCoreLazy.Setup;
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TearDown;
|
||||
begin
|
||||
end;
|
||||
|
||||
// == Tests for TMycNullLazy<T> ==
|
||||
procedure TTestMycCoreLazy.TestNullLazy_GetChanged_IsAlwaysNullState;
|
||||
var
|
||||
nullLazy: IMycLazy<Integer>;
|
||||
changedState: IMycState;
|
||||
begin
|
||||
nullLazy := TMycNullLazy<Integer>.Create as IMycLazy<Integer>;
|
||||
Assert.IsNotNull(nullLazy, 'TMycNullLazy<Integer> instance should not be nil');
|
||||
changedState := nullLazy.GetChanged;
|
||||
Assert.AreSame(TState.Null, changedState, 'TMycNullLazy.GetChanged should return TState.Null');
|
||||
Assert.IsTrue(changedState.IsSet, 'TState.Null should always be set');
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestNullLazy_Pop_ReturnsDefaultIntegerAndTrue;
|
||||
var
|
||||
nullLazy: IMycLazy<Integer>;
|
||||
value: Integer;
|
||||
result: Boolean;
|
||||
begin
|
||||
nullLazy := TMycNullLazy<Integer>.Create as IMycLazy<Integer>;
|
||||
Assert.IsNotNull(nullLazy, 'TMycNullLazy<Integer> instance should not be nil');
|
||||
value := 123;
|
||||
result := nullLazy.Pop(value);
|
||||
Assert.IsTrue(result, 'TMycNullLazy.Pop should return true');
|
||||
Assert.AreEqual(Default(Integer), value, 'Value should be Default(Integer) after Pop');
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestNullLazy_Pop_ReturnsDefaultStringAndTrue;
|
||||
var
|
||||
nullLazy: IMycLazy<string>;
|
||||
value: string;
|
||||
result: Boolean;
|
||||
begin
|
||||
nullLazy := TMycNullLazy<string>.Create as IMycLazy<string>;
|
||||
Assert.IsNotNull(nullLazy, 'TMycNullLazy<string> instance should not be nil');
|
||||
value := 'test';
|
||||
result := nullLazy.Pop(value);
|
||||
Assert.IsTrue(result, 'TMycNullLazy.Pop should return true');
|
||||
Assert.AreEqual(Default(string), value, 'Value should be Default(string) after Pop');
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestNullLazy_Pop_ReturnsDefaultInterfaceAndTrue;
|
||||
var
|
||||
nullLazy: IMycLazy<IMycState>;
|
||||
value: IMycState;
|
||||
result: Boolean;
|
||||
begin
|
||||
nullLazy := TMycNullLazy<IMycState>.Create as IMycLazy<IMycState>;
|
||||
Assert.IsNotNull(nullLazy, 'TMycNullLazy<IMycState> instance should not be nil');
|
||||
value := TState.Null;
|
||||
result := nullLazy.Pop(value);
|
||||
Assert.IsTrue(result, 'TMycNullLazy.Pop should return true');
|
||||
Assert.IsNull(value, 'Value should be nil for an interface type after Pop from NullLazy');
|
||||
end;
|
||||
|
||||
// == Tests for TMycFuncLazy<T> - Initial State by Design ==
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_GetChanged_IsAlwaysTrueAfterCreation;
|
||||
var
|
||||
funcLazy: IMycLazy<Integer>;
|
||||
changedState: IMycState;
|
||||
sourceDirty: IMycDirty;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
sourceDirty.Reset;
|
||||
funcLazy := TMycFuncLazy<Integer>.Create(sourceDirty.State, function: Integer begin Result := 10; end);
|
||||
Assert.IsNotNull(funcLazy, 'TMycFuncLazy<Integer> instance should not be nil');
|
||||
changedState := funcLazy.GetChanged;
|
||||
Assert.IsNotNull(changedState, 'funcLazy.GetChanged should return a valid IMycState');
|
||||
Assert.IsTrue(changedState.IsSet, 'By design, funcLazy.GetChanged.IsSet should be true immediately after creation');
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_FirstPop_AlwaysEvaluatesAndResetsChanged;
|
||||
var
|
||||
funcLazy: IMycLazy<Integer>;
|
||||
value: Integer;
|
||||
result: Boolean;
|
||||
sourceDirty: IMycDirty;
|
||||
procExecuted: Boolean;
|
||||
expectedValue: Integer;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
sourceDirty.Reset;
|
||||
procExecuted := False;
|
||||
expectedValue := 50;
|
||||
funcLazy := TMycFuncLazy<Integer>.Create(sourceDirty.State,
|
||||
function: Integer
|
||||
begin
|
||||
procExecuted := True;
|
||||
Result := expectedValue;
|
||||
end);
|
||||
Assert.IsNotNull(funcLazy, 'TMycFuncLazy<Integer> instance should not be nil');
|
||||
Assert.IsTrue(funcLazy.GetChanged.IsSet, 'Changed.IsSet should be true before the first Pop by design');
|
||||
value := 0;
|
||||
result := funcLazy.Pop(value);
|
||||
Assert.IsTrue(result, 'The first Pop should return true by design, indicating evaluation');
|
||||
Assert.IsTrue(procExecuted, 'FProc should have been executed on the first Pop');
|
||||
Assert.AreEqual(expectedValue, value, 'Value should be the result from FProc after the first Pop');
|
||||
Assert.IsFalse(funcLazy.GetChanged.IsSet, 'Changed.IsSet should be false after the first Pop, as Pop resets it');
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_Pop_WhenProcIsNull_FirstPopReturnsTrueAndValueUnchanged_ResetsChanged;
|
||||
var
|
||||
funcLazy: IMycLazy<Integer>;
|
||||
value: Integer;
|
||||
preCallValue: Integer;
|
||||
result: Boolean;
|
||||
sourceDirty: IMycDirty;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
sourceDirty.Reset;
|
||||
funcLazy := TMycFuncLazy<Integer>.Create(sourceDirty.State, nil);
|
||||
Assert.IsNotNull(funcLazy, 'TMycFuncLazy<Integer> instance should not be nil');
|
||||
Assert.IsTrue(funcLazy.GetChanged.IsSet, 'Changed state should be true before Pop by design');
|
||||
preCallValue := 123;
|
||||
value := preCallValue;
|
||||
result := funcLazy.Pop(value);
|
||||
Assert.IsTrue(result, 'First Pop should return true by design, even if FProc is nil');
|
||||
Assert.AreEqual(preCallValue, value, 'Value should be unchanged as FProc was nil and current Pop implementation does not assign Default(T)');
|
||||
Assert.IsFalse(funcLazy.GetChanged.IsSet, 'Changed state should be false after Pop');
|
||||
end;
|
||||
|
||||
// == Tests for TMycFuncLazy<T> - Behavior After Initial Pop ==
|
||||
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_AfterFirstPop_IfNoSourceChange_GetChangedIsFalse;
|
||||
var
|
||||
funcLazy: IMycLazy<Integer>;
|
||||
sourceDirty: IMycDirty;
|
||||
initialProcValue: Integer;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
sourceDirty.Reset;
|
||||
initialProcValue := 33;
|
||||
funcLazy := TMycFuncLazy<Integer>.Create(sourceDirty.State, function: Integer begin Result := initialProcValue; end);
|
||||
Helper_ConsumeInitialPop(funcLazy, initialProcValue);
|
||||
Assert.IsFalse(funcLazy.GetChanged.IsSet, 'After initial Pop and no source change, GetChanged.IsSet should be false');
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_AfterFirstPop_IfNoSourceChange_PopReturnsFalse_ValueUndefined;
|
||||
var
|
||||
funcLazy: IMycLazy<Integer>;
|
||||
value: Integer;
|
||||
result: Boolean;
|
||||
sourceDirty: IMycDirty;
|
||||
initialProcValue: Integer;
|
||||
procExecutedCount: Integer;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
sourceDirty.Reset;
|
||||
initialProcValue := 44;
|
||||
procExecutedCount := 0;
|
||||
funcLazy := TMycFuncLazy<Integer>.Create(sourceDirty.State,
|
||||
function: Integer
|
||||
begin
|
||||
Inc(procExecutedCount);
|
||||
Result := initialProcValue;
|
||||
end);
|
||||
Helper_ConsumeInitialPop(funcLazy, initialProcValue);
|
||||
Assert.AreEqual(1, procExecutedCount, 'Proc should have executed once for initial pop');
|
||||
result := funcLazy.Pop(value);
|
||||
Assert.IsFalse(result, 'Second Pop (after initial, no source change) should return false');
|
||||
Assert.AreEqual(1, procExecutedCount, 'Proc should not have executed again');
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_AfterSourceChange_GetChanged_IsSet;
|
||||
var
|
||||
funcLazy: IMycLazy<Integer>;
|
||||
changedState: IMycState;
|
||||
sourceDirty: IMycDirty;
|
||||
initialProcValue: Integer;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
sourceDirty.Reset;
|
||||
initialProcValue := 20;
|
||||
funcLazy := TMycFuncLazy<Integer>.Create(sourceDirty.State, function: Integer begin Result := initialProcValue; end);
|
||||
Helper_ConsumeInitialPop(funcLazy, initialProcValue);
|
||||
sourceDirty.Notify;
|
||||
changedState := funcLazy.GetChanged;
|
||||
Assert.IsTrue(changedState.IsSet, 'After source change (post-initial pop), funcLazy.GetChanged.IsSet should be true');
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_AfterSourceChange_Pop_ReturnsTrueAndProcResult_ResetsChanged;
|
||||
var
|
||||
funcLazy: IMycLazy<Integer>;
|
||||
value: Integer;
|
||||
result: Boolean;
|
||||
sourceDirty: IMycDirty;
|
||||
procCallCount: Integer;
|
||||
currentExpectedValue: Integer;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
sourceDirty.Reset;
|
||||
procCallCount := 0;
|
||||
funcLazy := TMycFuncLazy<Integer>.Create(sourceDirty.State,
|
||||
function: Integer
|
||||
begin
|
||||
Inc(procCallCount);
|
||||
if procCallCount = 1 then Result := 30
|
||||
else Result := 300 + procCallCount;
|
||||
end);
|
||||
currentExpectedValue := 30;
|
||||
Helper_ConsumeInitialPop(funcLazy, currentExpectedValue);
|
||||
Assert.AreEqual(1, procCallCount, 'Proc executed for initial Pop');
|
||||
sourceDirty.Notify;
|
||||
Assert.IsTrue(funcLazy.GetChanged.IsSet, 'Changed state should be true after source notification');
|
||||
value := 0;
|
||||
result := funcLazy.Pop(value);
|
||||
currentExpectedValue := 300 + 2;
|
||||
Assert.IsTrue(result, 'Pop should return true after source changed');
|
||||
Assert.AreEqual(2, procCallCount, 'Proc should have been executed again');
|
||||
Assert.AreEqual(currentExpectedValue, value, 'Value should be the new result of FProc');
|
||||
Assert.IsFalse(funcLazy.GetChanged.IsSet, 'Changed state should be false after Pop');
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_Pop_Twice_SourceUnchanged_SecondPopReturnsFalse_ValueUndefined;
|
||||
var
|
||||
funcLazy: IMycLazy<Integer>;
|
||||
value: Integer;
|
||||
resultPop1, resultPop2: Boolean;
|
||||
sourceDirty: IMycDirty;
|
||||
procCallCount: Integer;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
sourceDirty.Reset;
|
||||
procCallCount := 0;
|
||||
funcLazy := TMycFuncLazy<Integer>.Create(sourceDirty.State,
|
||||
function: Integer
|
||||
begin
|
||||
Inc(procCallCount);
|
||||
Result := 40;
|
||||
end);
|
||||
resultPop1 := funcLazy.Pop(value);
|
||||
Assert.IsTrue(resultPop1, 'First Pop should return true by design');
|
||||
Assert.AreEqual(40, value, 'Value from first Pop');
|
||||
Assert.AreEqual(1, procCallCount, 'Proc called for first Pop');
|
||||
Assert.IsFalse(funcLazy.GetChanged.IsSet, 'Changed state should be false after first Pop');
|
||||
resultPop2 := funcLazy.Pop(value);
|
||||
Assert.IsFalse(resultPop2, 'Second Pop should return false as state was reset and not changed again by source');
|
||||
Assert.AreEqual(1, procCallCount, 'Proc should not be called for second Pop if no source change');
|
||||
end;
|
||||
|
||||
// TestFuncLazy_SourceChanges_Pop_SourceChangesAgain_PopAgain has been RENAMED and RESTRUCTURED
|
||||
// to TestFuncLazy_SourceInteraction_NotifyOnSetSourceDoesNotRetriggerLazy
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_SourceInteraction_NotifyOnSetSourceDoesNotRetriggerLazy;
|
||||
var
|
||||
funcLazy: IMycLazy<Integer>;
|
||||
value: Integer;
|
||||
result: Boolean;
|
||||
sourceDirty: IMycDirty;
|
||||
procCallCount: Integer;
|
||||
initialValue, firstSourceChangeValue: Integer;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
sourceDirty.Reset; // sourceDirty.IsSet is FALSE
|
||||
procCallCount := 0;
|
||||
initialValue := 51;
|
||||
firstSourceChangeValue := 52;
|
||||
|
||||
funcLazy := TMycFuncLazy<Integer>.Create(sourceDirty.State,
|
||||
function: Integer
|
||||
begin
|
||||
Inc(procCallCount);
|
||||
if procCallCount = 1 then Result := initialValue // For initial pop
|
||||
else if procCallCount = 2 then Result := firstSourceChangeValue // For pop after first effective source change
|
||||
else Result := 999; // Should not be reached in this specific test logic
|
||||
end);
|
||||
|
||||
// 1. Initial Pop (consumes "by design" changed state)
|
||||
Assert.IsTrue(funcLazy.GetChanged.IsSet, 'Changed state should be true before first Pop (by design)');
|
||||
result := funcLazy.Pop(value); // procCallCount becomes 1
|
||||
Assert.IsTrue(result, 'First Pop should return true');
|
||||
Assert.AreEqual(initialValue, value, 'Value from first Pop');
|
||||
Assert.AreEqual(1, procCallCount, 'Proc called for initial Pop');
|
||||
Assert.IsFalse(funcLazy.GetChanged.IsSet, 'Changed state should be false after first Pop');
|
||||
|
||||
// 2. First effective source change (sourceDirty: false -> true)
|
||||
sourceDirty.Notify; // sourceDirty.IsSet becomes TRUE, notifies funcLazy.FChanged, funcLazy.GetChanged.IsSet becomes TRUE
|
||||
Assert.IsTrue(sourceDirty.State.IsSet, 'sourceDirty should be set after first Notify');
|
||||
Assert.IsTrue(funcLazy.GetChanged.IsSet, 'Changed state should be true after first effective source notification');
|
||||
result := funcLazy.Pop(value); // procCallCount becomes 2
|
||||
Assert.IsTrue(result, 'Pop after first effective source change should return true');
|
||||
Assert.AreEqual(firstSourceChangeValue, value, 'Value from Pop after first effective source change');
|
||||
Assert.AreEqual(2, procCallCount, 'Proc called again');
|
||||
Assert.IsFalse(funcLazy.GetChanged.IsSet, 'Changed state should be false after second Pop');
|
||||
|
||||
// 3. Notify sourceDirty again (sourceDirty is already TRUE)
|
||||
Assert.IsTrue(sourceDirty.State.IsSet, 'sourceDirty is still set before second Notify attempt');
|
||||
sourceDirty.Notify; // Since sourceDirty is already set, this does NOT notify funcLazy.FChanged.
|
||||
// funcLazy.GetChanged.IsSet remains FALSE.
|
||||
|
||||
Assert.IsFalse(funcLazy.GetChanged.IsSet, 'Changed state should REMAIN false after Notify on an already-set source');
|
||||
|
||||
// 4. Attempt to Pop again
|
||||
result := funcLazy.Pop(value); // procCallCount should remain 2
|
||||
Assert.IsFalse(result, 'Pop after Notify on an already-set source should return false');
|
||||
Assert.AreEqual(2, procCallCount, 'Proc should NOT have been called again');
|
||||
// Value of 'value' is undefined here and not checked.
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_Destroy_UnsubscribesFromSource;
|
||||
var
|
||||
funcLazyObj: TMycFuncLazy<Integer>;
|
||||
sourceDirty: IMycDirty;
|
||||
tempVal: Integer;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
sourceDirty.Reset;
|
||||
funcLazyObj := TMycFuncLazy<Integer>.Create(sourceDirty.State, function: Integer begin Result := 1; end);
|
||||
Assert.IsTrue(funcLazyObj.Pop(tempVal), 'Initial Pop should succeed');
|
||||
funcLazyObj.Destroy;
|
||||
funcLazyObj := nil;
|
||||
Assert.WillNotRaise(
|
||||
procedure
|
||||
begin
|
||||
sourceDirty.Notify;
|
||||
end,
|
||||
nil,
|
||||
'Destroy test assumes TMycSubscription.Unsubscribe works. Verified by no crash on source notify post-destroy.');
|
||||
sourceDirty := nil;
|
||||
end;
|
||||
|
||||
procedure TTestMycCoreLazy.TestFuncLazy_SourceIsInitiallySet_PopBehavesCorrectly;
|
||||
var
|
||||
funcLazy: IMycLazy<Integer>;
|
||||
value: Integer;
|
||||
result: Boolean;
|
||||
sourceDirty: IMycDirty;
|
||||
expectedValue: Integer;
|
||||
procExecuted: Boolean;
|
||||
begin
|
||||
sourceDirty := TDirty.Construct;
|
||||
Assert.IsTrue(sourceDirty.State.IsSet, 'SourceDirty should be initially set for this test scenario');
|
||||
expectedValue := 70;
|
||||
procExecuted := False;
|
||||
funcLazy := TMycFuncLazy<Integer>.Create(sourceDirty.State,
|
||||
function: Integer
|
||||
begin
|
||||
procExecuted := True;
|
||||
Result := expectedValue;
|
||||
end);
|
||||
Assert.IsNotNull(funcLazy, 'TMycFuncLazy<Integer> instance should not be nil');
|
||||
Assert.IsTrue(funcLazy.GetChanged.IsSet, 'funcLazy.GetChanged.IsSet should be true after creation (by design)');
|
||||
value := 0;
|
||||
result := funcLazy.Pop(value);
|
||||
Assert.IsTrue(result, 'First Pop should return true');
|
||||
Assert.IsTrue(procExecuted, 'FProc should have been executed on first Pop');
|
||||
Assert.AreEqual(expectedValue, value, 'Value should be the result of FProc');
|
||||
Assert.IsFalse(funcLazy.GetChanged.IsSet, 'Changed state should be false after the first Pop');
|
||||
end;
|
||||
|
||||
initialization
|
||||
TDUnitX.RegisterTestFixture(TTestMycCoreLazy);
|
||||
end.
|
||||
Reference in New Issue
Block a user