public void PowerOfTwoSizePackerTestValidSquares3()
        {
            //Arrange
            var inputSequence          = (TestUtil.Shuffle(TestUtil.GetIncreasingSquares(3)));
            var placementAlgorithmMock = new Mock <IPlacementAlgorithm>();

            placementAlgorithmMock
            .Setup(x => x.PlaceRects(It.IsAny <int>(), It.IsAny <int>(), inputSequence, It.IsAny <CancellationToken>()))
            .Returns <int, int, IEnumerable <PPRect>, CancellationToken>((w, h, rects, _) =>
            {
                //Assume "dumb" placement algorithm that simple places all the rects consecutively next to each other
                int maxH = rects.Max(x => x.Height);
                int sumW = rects.Sum(x => x.Width);
                if (sumW > w || maxH > h)
                {
                    return(null);
                }
                int left = 0;
                return(new PackingResult(sumW, maxH, rects.Select(x =>
                {
                    left += x.Width;
                    return new PPRect(left, 0, left, x.Height);
                })));;
            });
            var packer = new PowerOfTwoSizePacker(placementAlgorithmMock.Object);

            //Act
            var result = packer.FindMinimumBoundingBox(inputSequence);

            //Assert
            Assert.AreNotEqual(null, result);
            Assert.AreEqual(true, IsPoT(result.Width));
            Assert.AreEqual(true, IsPoT(result.Height));
            Assert.AreEqual(true, TestUtil.IsPackingResultValid(result));
        }
        public async Task PowerOfTwoSizePackerTestRunCancelled()
        {
            //Now we know that it was called atleast three times (from the previous test case), check that the use of cancellation reduce
            //it to two calls (it is called two times before the "main-loop" starts and the cancellation is
            //being checked in the main loop)
            var calledTimes            = 0;
            var inputSequence          = (TestUtil.Shuffle(TestUtil.GetIncreasingSquares(50)));
            var placementAlgorithmMock = new Mock <IPlacementAlgorithm>();

            placementAlgorithmMock
            .Setup(x => x.PlaceRects(It.IsAny <int>(), It.IsAny <int>(), inputSequence, It.IsAny <CancellationToken>()))
            .Returns <int, int, IEnumerable <PPRect>, CancellationToken>((w, h, rects, _) =>
            {
                //Ensure that it is not too fast ...
                Thread.Sleep(1000);
                calledTimes++;
                //Assume "dumb" placement algorithm that simple places all the rects consecutively next to each other
                int maxH = rects.Max(x => x.Height);
                int sumW = rects.Sum(x => x.Width);
                if (sumW > w || maxH > h)
                {
                    return(null);
                }
                int left = 0;
                return(new PackingResult(sumW, maxH, rects.Select(x =>
                {
                    left += x.Width;
                    return new PPRect(left, 0, left, x.Height);
                })));;
            });

            var packer = new PowerOfTwoSizePacker(placementAlgorithmMock.Object);

            using var source = new CancellationTokenSource();
            var cancellationToken = source.Token;

            var task = Task.Run(() => packer.FindMinimumBoundingBox(inputSequence, cancellationToken));

            source.Cancel();

            var result = await task.ConfigureAwait(false);

            //Check that even though it was canceled, some meaningful result could be returned
            if (result != null)
            {
                Assert.AreNotEqual(null, result);
                Assert.AreEqual(true, IsPoT(result.Width));
                Assert.AreEqual(true, IsPoT(result.Height));
                //Check that the returned result is valid
                Assert.AreEqual(true, TestUtil.IsPackingResultValid(result));
            }

            Assert.IsTrue(calledTimes == 0);

            calledTimes = 0;
            var result2 = packer.FindMinimumBoundingBox(inputSequence, cancellationToken);

            Assert.IsTrue(calledTimes == 0);
        }