public void GetItem_OfIntWhenInitialRetrievalTimesOut_ReturnsDefaultValueOfZero()
        {
            // Arrange
            InMemoryItemCache <int> cache = new InMemoryItemCache <int>(
                new NonCloningClonerFactory <int>(),
                null,
                () => { TimeDelay.WaitFor(200); return(125); },
                TimeSpan.FromMinutes(2),
                50, 50);
            int actualResult;
            int expectedResult = 0;

            // Act
            Task <int> task1 = new Task <int>(() => { return(cache.GetItem()); });
            Task <int> task2 = new Task <int>(() => { TimeDelay.WaitFor(50); return(cache.GetItem()); });

            // Start the 2 tasks, with task2 likely to have to wait on task1
            task1.Start();
            task2.Start();
            Task.WaitAll(task1, task2);
            actualResult = task2.Result;

            // Assert
            Assert.AreEqual(expectedResult, actualResult);
        }
        public void Invalidate_OfCacheableClassWhenCalledInvalidatedAndCalledAgain_ReturnsSecondCachedValue()
        {
            // Arrange
            int cachedValue = 100;
            AutoRefreshingItemCache <CacheableClass> cache = new AutoRefreshingItemCache <CacheableClass>(
                new FakeLogger(),
                (ct) => { cachedValue += 25; return(Task.FromResult(new CacheableClass(cachedValue))); },
                null,
                TimeSpan.FromMinutes(2)
                );
            CacheableClass cachedClass;
            int            actualResult;
            int            expectedResult = 150;

            cache.Initialise();

            // Act
            _ = cache.GetItem();
            cache.Invalidate();
            TimeDelay.WaitFor(50);
            cachedClass  = cache.GetItem();
            actualResult = cachedClass.GetValue();

            // Assert
            Assert.AreEqual(expectedResult, actualResult);
        }
        public void Invalidate_OfIntWhenCalledInvalidatedAndCalledAgain_ReturnsSecondCachedValue()
        {
            // Arrange
            int cachedValue = 100;
            AutoRefreshingItemCache <int> cache = new AutoRefreshingItemCache <int>(
                new FakeLogger(),
                new NonCloningClonerFactory <int>(),
                (ct) => { cachedValue += 25; return(Task.FromResult(cachedValue)); },
                0,
                TimeSpan.FromMinutes(2)
                );
            int actualResult;
            int expectedResult = 150;

            cache.Initialise();

            // Act
            _ = cache.GetItem();
            cache.Invalidate();
            TimeDelay.WaitFor(50);
            actualResult = cache.GetItem();

            // Assert
            Assert.AreEqual(expectedResult, actualResult);
        }
        public void GetItem_OfCacheableClassWhenCacheExpires_CallsRetrievalDelegateAgain()
        {
            // Arrange
            AutoRefreshingItemCache <CacheableClass> cache = new AutoRefreshingItemCache <CacheableClass>(
                new FakeLogger(),
                (ct) => { return(Task.FromResult(new CacheableClass(125))); },
                null,
                TimeSpan.FromMilliseconds(100));
            DateTime       initialCreatedAt;
            DateTime       finalCreatedAt;
            CacheableClass cacheItem;

            cache.Initialise();

            // Act
            cacheItem        = cache.GetItem();
            initialCreatedAt = cacheItem.CreatedAt;
            // Wait for the cache item to expire and then retry
            TimeDelay.WaitFor(150);
            cacheItem      = cache.GetItem();
            finalCreatedAt = cacheItem.CreatedAt;

            // Assert that the creation values are different
            Assert.AreNotEqual(initialCreatedAt, finalCreatedAt);
        }
        public void GetItem_OfCacheableClassWhenCacheExpires_CallsRetrievalDelegateAgain()
        {
            // Arrange
            InMemoryItemCache <CacheableClass> cache = new InMemoryItemCache <CacheableClass>(
                null,
                () => { return(new CacheableClass(125)); },
                TimeSpan.FromMilliseconds(100));
            DateTime       initialCreatedAt;
            DateTime       finalCreatedAt;
            CacheableClass cacheItem;

            // Act
            cacheItem        = cache.GetItem();
            initialCreatedAt = cacheItem.CreatedAt;
            // Wait for the cache item to expire and then retry
            TimeDelay.WaitFor(150);
            cacheItem      = cache.GetItem();
            finalCreatedAt = cacheItem.CreatedAt;

            // Assert that the creation values are different
            Assert.AreNotEqual(initialCreatedAt, finalCreatedAt);
        }
        public void GetItem_OfCacheableClassWhenInitialRetrievalTimesOut_ReturnsDefaultValueOfNull()
        {
            // Arrange
            InMemoryItemCache <CacheableClass> cache = new InMemoryItemCache <CacheableClass>(
                async() => { await TimeDelay.WaitForAsync(200); return(new CacheableClass(100)); },
                () => { TimeDelay.WaitFor(200); return(new CacheableClass(125)); },
                TimeSpan.FromMinutes(2),
                50, 50);
            CacheableClass cacheItem;

            // Act
            Task <CacheableClass> task1 = new Task <CacheableClass>(() => { return(cache.GetItem()); });
            Task <CacheableClass> task2 = new Task <CacheableClass>(() => { TimeDelay.WaitFor(60); return(cache.GetItem()); });

            // Start the 2 tasks, with task2 likely to have to wait on task1
            task1.Start();
            task2.Start();
            Task.WaitAll(task1, task2);
            cacheItem = task2.Result;

            // Assert
            Assert.IsNull(cacheItem);
        }