unit MultiselectMoveTestCase; interface uses System.Generics.Collections, TestFramework; type TMultiselectMoveTest = class(TTestCase) private FList: TList; protected procedure SetUp; override; procedure TearDown; override; procedure CheckList(AExpected: array of Integer); procedure Move(ASelection: array of Integer; ATargetIndex: Integer); property List: TList read FList; published procedure TestSetUp; procedure TestSingleDown; procedure TestSingleUp; procedure TestSingleMin; procedure TestSingleMax; procedure TestMultipleDown; procedure TestMultipleUp; procedure TestMultipleMin; procedure TestMultipleMax; procedure TestGapDown; procedure TestGapUp; procedure TestGapMiddle; procedure TestGapMin; procedure TestGapMax; end; implementation uses System.SysUtils; { TMultiselectMoveTest } procedure TMultiselectMoveTest.SetUp; var value: Integer; begin inherited SetUp; FList := TList.Create; for value := 0 to 9 do FList.Add(value); end; procedure TMultiselectMoveTest.TearDown; begin FreeAndNil(FList); inherited TearDown; end; procedure TMultiselectMoveTest.CheckList(AExpected: array of Integer); var listValues: TStringBuilder; expectedValues: TStringBuilder; value: Integer; begin listValues := nil; expectedValues := nil; try listValues := TStringBuilder.Create; for value in List do listValues.Append(value).Append(','); expectedValues := TStringBuilder.Create; for value in AExpected do expectedValues.Append(value).Append(','); CheckEquals(expectedValues.ToString, listValues.ToString); finally FreeAndNil(expectedValues); FreeAndNil(listValues); end; end; procedure TMultiselectMoveTest.Move(ASelection: array of Integer; ATargetIndex: Integer); var targetIndex: Integer; sourceShift: Integer; index: Integer; sourceIndex: Integer; begin targetIndex := ATargetIndex; sourceShift := 0; for index in ASelection do begin sourceIndex := index; if index < ATargetIndex then Inc(sourceIndex, sourceShift); if targetIndex > sourceIndex then begin List.Move(sourceIndex, Pred(targetIndex)); Dec(sourceShift); end else if targetIndex < sourceIndex then begin List.Move(sourceIndex, targetIndex); Inc(targetIndex); end; end; end; procedure TMultiselectMoveTest.TestSetUp; begin CheckList([0,1,2,3,4,5,6,7,8,9]); end; procedure TMultiselectMoveTest.TestSingleDown; begin Move([1], 5); CheckList([0,2,3,4,1,5,6,7,8,9]); end; procedure TMultiselectMoveTest.TestSingleMin; begin Move([5], 0); CheckList([5,0,1,2,3,4,6,7,8,9]); end; procedure TMultiselectMoveTest.TestSingleMax; begin Move([5], 10); CheckList([0,1,2,3,4,6,7,8,9,5]); end; procedure TMultiselectMoveTest.TestSingleUp; begin Move([8], 5); CheckList([0,1,2,3,4,8,5,6,7,9]); end; procedure TMultiselectMoveTest.TestMultipleDown; begin Move([1,2], 5); CheckList([0,3,4,1,2,5,6,7,8,9]); end; procedure TMultiselectMoveTest.TestMultipleUp; begin Move([5,6], 1); CheckList([0,5,6,1,2,3,4,7,8,9]); end; procedure TMultiselectMoveTest.TestMultipleMin; begin Move([5,6,7], 0); CheckList([5,6,7,0,1,2,3,4,8,9]); end; procedure TMultiselectMoveTest.TestMultipleMax; begin Move([3,4,5], 10); CheckList([0,1,2,6,7,8,9,3,4,5]); end; procedure TMultiselectMoveTest.TestGapDown; begin Move([3,5], 6); CheckList([0,1,2,4,3,5,6,7,8,9]); end; procedure TMultiselectMoveTest.TestGapUp; begin Move([7,9], 3); CheckList([0,1,2,7,9,3,4,5,6,8]); end; procedure TMultiselectMoveTest.TestGapMiddle; begin Move([3,8], 5); CheckList([0,1,2,4,3,8,5,6,7,9]); end; procedure TMultiselectMoveTest.TestGapMin; begin Move([3,5,8], 0); CheckList([3,5,8,0,1,2,4,6,7,9]); end; procedure TMultiselectMoveTest.TestGapMax; begin Move([4,6,9], 10); CheckList([0,1,2,3,5,7,8,4,6,9]); end; initialization RegisterTest(TMultiselectMoveTest.Suite); end.