void TestPrimitiveObjectPoolsCreation()
        {
            PrimitiveObjectPool <TestObjectPoolItem>          primPool   = null;
            ResizablePrimitiveObjectPool <TestObjectPoolItem> resizePool = null;
            BlockingPrimitiveObjectPool <TestObjectPoolItem>  blockPool  = null;

            Assert.Throws <ArgumentOutOfRangeException>(() =>
            {
                primPool = new PrimitiveObjectPool <TestObjectPoolItem>(0);
            });

            Assert.Throws <ArgumentOutOfRangeException>(() =>
            {
                resizePool = new ResizablePrimitiveObjectPool <TestObjectPoolItem>(0);
            });

            Assert.Throws <ArgumentOutOfRangeException>(() =>
            {
                blockPool = new BlockingPrimitiveObjectPool <TestObjectPoolItem>(0);
            });

            Assert.Null(primPool);
            Assert.Null(resizePool);
            Assert.Null(blockPool);

            primPool   = new PrimitiveObjectPool <TestObjectPoolItem>(1);
            resizePool = new ResizablePrimitiveObjectPool <TestObjectPoolItem>(1);
            blockPool  = new BlockingPrimitiveObjectPool <TestObjectPoolItem>(1);

            Assert.NotNull(primPool);
            Assert.NotNull(resizePool);
            Assert.NotNull(blockPool);
        }
        void TestPrimitiveObjectPoolsDispose()
        {
            PrimitiveObjectPool <TestObjectPoolItem>          primPool   = new PrimitiveObjectPool <TestObjectPoolItem>(1);
            ResizablePrimitiveObjectPool <TestObjectPoolItem> resizePool = new ResizablePrimitiveObjectPool <TestObjectPoolItem>(1);
            BlockingPrimitiveObjectPool <TestObjectPoolItem>  blockPool  = new BlockingPrimitiveObjectPool <TestObjectPoolItem>(1);

            primPool.Dispose();
            resizePool.Dispose();
            blockPool.Dispose();

            Assert.Throws <ObjectDisposedException>(() => primPool.InUse);
            Assert.Throws <ObjectDisposedException>(() => primPool.PoolCount);
            Assert.Throws <ObjectDisposedException>(() => primPool.Size);
            Assert.Throws <ObjectDisposedException>(() => primPool.TryObtain(out var item));
            Assert.Throws <ObjectDisposedException>(() => primPool.TryRelease(new TestObjectPoolItem()));
            Assert.Throws <ObjectDisposedException>(() => primPool.Obtain());
            Assert.Throws <ObjectDisposedException>(() => primPool.Release(new TestObjectPoolItem()));

            Assert.Throws <ObjectDisposedException>(() => resizePool.InUse);
            Assert.Throws <ObjectDisposedException>(() => resizePool.PoolCount);
            Assert.Throws <ObjectDisposedException>(() => resizePool.Size);
            Assert.Throws <ObjectDisposedException>(() => resizePool.TryObtain(out var item));
            Assert.Throws <ObjectDisposedException>(() => resizePool.TryRelease(new TestObjectPoolItem()));
            Assert.Throws <ObjectDisposedException>(() => resizePool.Obtain());
            Assert.Throws <ObjectDisposedException>(() => resizePool.Release(new TestObjectPoolItem()));

            Assert.Throws <ObjectDisposedException>(() => blockPool.InUse);
            Assert.Throws <ObjectDisposedException>(() => blockPool.PoolCount);
            Assert.Throws <ObjectDisposedException>(() => blockPool.Size);
            Assert.Throws <ObjectDisposedException>(() => blockPool.TryObtain(out var item));
            Assert.Throws <ObjectDisposedException>(() => blockPool.TryRelease(new TestObjectPoolItem()));
            Assert.Throws <ObjectDisposedException>(() => blockPool.Obtain());
            Assert.Throws <ObjectDisposedException>(() => blockPool.Release(new TestObjectPoolItem()));
        }
        void TestResizablePrimitiveObjectPoolObtainRelease()
        {
            ResizablePrimitiveObjectPool <TestObjectPoolItem> resizePool = new ResizablePrimitiveObjectPool <TestObjectPoolItem>(3);

            Assert.Equal(3, resizePool.Size);
            Assert.Equal(0, resizePool.InUse);
            Assert.Equal(3, resizePool.PoolCount);

            TestObjectPoolItem test = new TestObjectPoolItem();

            Assert.False(resizePool.TryRelease(test));

            Assert.Equal(3, resizePool.Size);
            Assert.Equal(0, resizePool.InUse);
            Assert.Equal(3, resizePool.PoolCount);

            resizePool.Release(test);

            Assert.Equal(4, resizePool.Size);
            Assert.Equal(0, resizePool.InUse);
            Assert.Equal(4, resizePool.PoolCount);

            TestObjectPoolItem test1;
            TestObjectPoolItem test2;
            TestObjectPoolItem test3;
            TestObjectPoolItem test4;
            TestObjectPoolItem test5;

            Assert.True(resizePool.TryObtain(out test1));

            Assert.NotNull(test1);
            Assert.Equal(4, resizePool.Size);
            Assert.Equal(1, resizePool.InUse);
            Assert.Equal(3, resizePool.PoolCount);

            test2 = resizePool.Obtain();

            Assert.NotNull(test2);
            Assert.Equal(4, resizePool.Size);
            Assert.Equal(2, resizePool.InUse);
            Assert.Equal(2, resizePool.PoolCount);

            test3 = resizePool.Obtain();

            Assert.NotNull(test3);
            Assert.Equal(4, resizePool.Size);
            Assert.Equal(3, resizePool.InUse);
            Assert.Equal(1, resizePool.PoolCount);

            test4 = resizePool.Obtain();

            Assert.NotNull(test4);
            Assert.Equal(4, resizePool.Size);
            Assert.Equal(4, resizePool.InUse);
            Assert.Equal(0, resizePool.PoolCount);

            Assert.False(resizePool.TryObtain(out test5));

            Assert.Null(test5);
            Assert.Equal(4, resizePool.Size);
            Assert.Equal(4, resizePool.InUse);
            Assert.Equal(0, resizePool.PoolCount);

            test5 = resizePool.Obtain();

            Assert.NotNull(test5);
            Assert.Equal(5, resizePool.Size);
            Assert.Equal(5, resizePool.InUse);
            Assert.Equal(0, resizePool.PoolCount);

            Assert.True(resizePool.TryRelease(test5));

            Assert.Equal(5, resizePool.Size);
            Assert.Equal(4, resizePool.InUse);
            Assert.Equal(1, resizePool.PoolCount);

            resizePool.Release(test5);

            Assert.Equal(5, resizePool.Size);
            Assert.Equal(3, resizePool.InUse);
            Assert.Equal(2, resizePool.PoolCount);

            resizePool.Release(test5);

            Assert.Equal(5, resizePool.Size);
            Assert.Equal(2, resizePool.InUse);
            Assert.Equal(3, resizePool.PoolCount);

            resizePool.Release(test5);

            Assert.Equal(5, resizePool.Size);
            Assert.Equal(1, resizePool.InUse);
            Assert.Equal(4, resizePool.PoolCount);

            resizePool.Release(test5);

            Assert.Equal(5, resizePool.Size);
            Assert.Equal(0, resizePool.InUse);
            Assert.Equal(5, resizePool.PoolCount);

            resizePool.Release(test5);

            Assert.Equal(6, resizePool.Size);
            Assert.Equal(0, resizePool.InUse);
            Assert.Equal(6, resizePool.PoolCount);
        }