Added tests for LRUCache.
Moved core test code to reflect changes in core code. Removed unused using directives.
This commit is contained in:
parent
35a2765559
commit
f5a181d2f2
@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace GameServiceWarden.Core.Module
|
namespace GameServiceWarden.Core.Collection
|
||||||
{
|
{
|
||||||
public class LRUCache<K, V>
|
public class LRUCache<K, V> : IEnumerable<V>
|
||||||
{
|
{
|
||||||
private class Node
|
private class Node
|
||||||
{
|
{
|
||||||
@ -14,7 +15,7 @@ namespace GameServiceWarden.Core.Module
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int Size {get { return size; } }
|
public int Size {get { return size; } }
|
||||||
public int Length {get { return valueDictionary.Count; } }
|
public int Count {get { return valueDictionary.Count; } }
|
||||||
private readonly int size;
|
private readonly int size;
|
||||||
private Node top;
|
private Node top;
|
||||||
private Node bottom;
|
private Node bottom;
|
||||||
@ -49,7 +50,7 @@ namespace GameServiceWarden.Core.Module
|
|||||||
bottom = node;
|
bottom = node;
|
||||||
} else if (valueDictionary.Count == Size) {
|
} else if (valueDictionary.Count == Size) {
|
||||||
valueDictionary.Remove(bottom.key);
|
valueDictionary.Remove(bottom.key);
|
||||||
cleanupAction(bottom.value);
|
cleanupAction?.Invoke(bottom.value);
|
||||||
bottom = bottom.front;
|
bottom = bottom.front;
|
||||||
}
|
}
|
||||||
valueDictionary[key] = node;
|
valueDictionary[key] = node;
|
||||||
@ -68,10 +69,27 @@ namespace GameServiceWarden.Core.Module
|
|||||||
return value.value;
|
return value.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsCached(K key) {
|
||||||
|
return valueDictionary.ContainsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
public void Clear() {
|
public void Clear() {
|
||||||
top = null;
|
top = null;
|
||||||
bottom = null;
|
bottom = null;
|
||||||
valueDictionary.Clear();
|
valueDictionary.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerator<V> GetEnumerator()
|
||||||
|
{
|
||||||
|
foreach (Node node in valueDictionary.Values)
|
||||||
|
{
|
||||||
|
yield return node.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,14 +2,10 @@ using System;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Pipes;
|
|
||||||
using System.Linq;
|
|
||||||
using GameServiceWarden.API.Games;
|
using GameServiceWarden.API.Games;
|
||||||
using GameServiceWarden.Core.Persistence;
|
using GameServiceWarden.Core.Persistence;
|
||||||
using GameServiceWarden.API.Module;
|
using GameServiceWarden.API.Module;
|
||||||
using System.Text;
|
using GameServiceWarden.Core.Collection;
|
||||||
|
|
||||||
namespace GameServiceWarden.Core.Module
|
namespace GameServiceWarden.Core.Module
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GameServiceWarden.Core.Tests.Collection
|
||||||
|
{
|
||||||
|
public class FakeDisposable : IDisposable
|
||||||
|
{
|
||||||
|
private string value;
|
||||||
|
private bool disposedValue;
|
||||||
|
|
||||||
|
public FakeDisposable(string value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsDisposed() {
|
||||||
|
return disposedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposedValue)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
disposedValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(disposing: true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
using GameServiceWarden.Core.Collection;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace GameServiceWarden.Core.Tests.Collection
|
||||||
|
{
|
||||||
|
public class LRUCacheTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Use_SufficientSpace_StoredUsed()
|
||||||
|
{
|
||||||
|
//Given
|
||||||
|
string data = "data";
|
||||||
|
LRUCache<int, string> cache = new LRUCache<int, string>(10);
|
||||||
|
//When
|
||||||
|
cache.Use(0, () => data);
|
||||||
|
//Then
|
||||||
|
Assert.Same(data, cache.Use(0, () => "other"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Use_InsufficientSpace_LastUsedRemoved()
|
||||||
|
{
|
||||||
|
//Given
|
||||||
|
string[] data = new string[] { "a", "b", "c" };
|
||||||
|
LRUCache<int, string> cache = new LRUCache<int, string>(2);
|
||||||
|
//When
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
cache.Use(i, () => data[i]);
|
||||||
|
}
|
||||||
|
//Then
|
||||||
|
Assert.Contains("c", cache);
|
||||||
|
Assert.Contains("b", cache);
|
||||||
|
Assert.DoesNotContain("a", cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IsCached_CachedData_True()
|
||||||
|
{
|
||||||
|
//Given
|
||||||
|
string[] data = new string[] { "a", "b", "c" };
|
||||||
|
LRUCache<int, string> cache = new LRUCache<int, string>(2);
|
||||||
|
//When
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
cache.Use(i, () => data[i]);
|
||||||
|
}
|
||||||
|
//Then
|
||||||
|
Assert.True(cache.IsCached(2));
|
||||||
|
Assert.True(cache.IsCached(1));
|
||||||
|
Assert.False(cache.IsCached(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Use_CleanupDelSet_DataChanged()
|
||||||
|
{
|
||||||
|
//Given
|
||||||
|
FakeDisposable[] data = new FakeDisposable[] { new FakeDisposable("a"), new FakeDisposable("b"), new FakeDisposable("c")};
|
||||||
|
LRUCache<int, FakeDisposable> cache = new LRUCache<int, FakeDisposable>(2, (d) => d.Dispose());
|
||||||
|
//When
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
cache.Use(i, () => data[i]);
|
||||||
|
}
|
||||||
|
//Then
|
||||||
|
Assert.True(data[0].IsDisposed());
|
||||||
|
Assert.False(data[1].IsDisposed());
|
||||||
|
Assert.False(data[2].IsDisposed());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ using System.IO;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GameServiceWarden.API.Module;
|
using GameServiceWarden.API.Module;
|
||||||
|
|
||||||
namespace GameServiceWarden.Core.Tests.Modules.Games
|
namespace GameServiceWarden.Core.Tests.Modules
|
||||||
{
|
{
|
||||||
public class FakeService : IService
|
public class FakeService : IService
|
||||||
{
|
{
|
@ -1,6 +1,6 @@
|
|||||||
using GameServiceWarden.API.Module;
|
using GameServiceWarden.API.Module;
|
||||||
|
|
||||||
namespace GameServiceWarden.Core.Tests.Modules.Games
|
namespace GameServiceWarden.Core.Tests.Modules
|
||||||
{
|
{
|
||||||
public class FakeServiceConfigurable : IServiceConfigurable
|
public class FakeServiceConfigurable : IServiceConfigurable
|
||||||
{
|
{
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using GameServiceWarden.API.Games;
|
using GameServiceWarden.API.Games;
|
||||||
using GameServiceWarden.Core.Module;
|
using GameServiceWarden.Core.Module;
|
||||||
|
|
||||||
namespace GameServiceWarden.Core.Tests.Modules.Games
|
namespace GameServiceWarden.Core.Tests.Modules
|
||||||
{
|
{
|
||||||
public class FakeServiceManagerMonitor : IServiceManagerMonitor
|
public class FakeServiceManagerMonitor : IServiceManagerMonitor
|
||||||
{
|
{
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using GameServiceWarden.API.Module;
|
using GameServiceWarden.API.Module;
|
||||||
|
|
||||||
namespace GameServiceWarden.Core.Tests.Modules.Games
|
namespace GameServiceWarden.Core.Tests.Modules
|
||||||
{
|
{
|
||||||
public class FakeServiceModule : IServiceModule
|
public class FakeServiceModule : IServiceModule
|
||||||
{
|
{
|
@ -7,7 +7,7 @@ using Xunit;
|
|||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace GameServiceWarden.Core.Tests.Modules.Games
|
namespace GameServiceWarden.Core.Tests.Modules
|
||||||
{
|
{
|
||||||
// Testing convention from: https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
|
// Testing convention from: https://docs.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
|
||||||
// fakes are generic test objects,
|
// fakes are generic test objects,
|
@ -12,7 +12,7 @@ using Xunit.Abstractions;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
||||||
namespace GameServiceWarden.Core.Tests.Modules.Games
|
namespace GameServiceWarden.Core.Tests.Modules
|
||||||
{
|
{
|
||||||
[CollectionDefinition("Service")]
|
[CollectionDefinition("Service")]
|
||||||
public class ServiceManagerTest
|
public class ServiceManagerTest
|
@ -1,10 +1,8 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using GameServiceWarden.Core.Module;
|
using GameServiceWarden.Core.Module;
|
||||||
using GameServiceWarden.Core.Persistence;
|
using GameServiceWarden.Core.Persistence;
|
||||||
using GameServiceWarden.Core.Tests.Modules;
|
using GameServiceWarden.Core.Tests.Modules;
|
||||||
using GameServiceWarden.Core.Tests.Modules.Games;
|
|
||||||
using GameServiceWarden.API.Module;
|
using GameServiceWarden.API.Module;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user