Skip to content

Commit

Permalink
☔ Implement tests for ConvertsLocator
Browse files Browse the repository at this point in the history
  • Loading branch information
pleonex committed Nov 29, 2023
1 parent 9ea472a commit 1716416
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public void FindFormatFromPluginsDir()
string pluginDir = Path.Combine(programDir, "Plugins");
TypeLocator.Instance.LoadContext.TryLoadFromDirectory(pluginDir, false);

var formats = ConvertersLocator.Instance.Formats;
var formats = ConverterLocator.Instance.Formats;
Assert.That(formats, Is.Not.Empty);
Assert.That(
formats.Select(t => t.Name),
Expand All @@ -142,11 +142,11 @@ public void FindConverterFromPluginsDir()
string pluginDir = Path.Combine(programDir, "Plugins");
TypeLocator.Instance.LoadContext.TryLoadFromDirectory(pluginDir, false);

Type poType = ConvertersLocator.Instance.Formats
Type poType = ConverterLocator.Instance.Formats
.Single(f => f.Name == "Yarhl.Media.Text.Po")
.Type;

var converters = ConvertersLocator.Instance.Converters
var converters = ConverterLocator.Instance.Converters
.Where(f => f.CanConvert(poType));
Assert.That(converters, Is.Not.Empty);
Assert.That(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ namespace Yarhl.Plugins.FileFormat;
/// <summary>
/// Locates converter types across assemblies and provide their information.
/// </summary>
public sealed class ConvertersLocator
public sealed class ConverterLocator
{
private static readonly object LockObj = new();
private static ConvertersLocator? singleInstance;
private static ConverterLocator? singleInstance;

private readonly List<InterfaceImplementationInfo> formatsMetadata;
private readonly List<ConverterTypeInfo> convertersMetadata;

/// <summary>
/// Initializes a new instance of the <see cref="ConvertersLocator"/> class.
/// Initializes a new instance of the <see cref="ConverterLocator"/> class.
/// </summary>
private ConvertersLocator()
private ConverterLocator()
{
formatsMetadata = new List<InterfaceImplementationInfo>();
Formats = formatsMetadata;
Expand All @@ -51,11 +51,11 @@ private ConvertersLocator()
/// Gets the plugin manager instance.
/// </summary>
/// <remarks><para>It initializes the manager if needed.</para></remarks>
public static ConvertersLocator Instance {
public static ConverterLocator Instance {
get {
if (singleInstance == null) {
lock (LockObj) {
singleInstance ??= new ConvertersLocator();
singleInstance ??= new ConverterLocator();
}
}

Expand All @@ -76,6 +76,10 @@ private ConvertersLocator()
/// <summary>
/// Scan the assemblies from the load context to look for formats and converters.
/// </summary>
/// <remarks>
/// This method is already called when the instance is created. Only needed
/// after loading additional assemblies.
/// </remarks>
public void ScanAssemblies()
{
formatsMetadata.Clear();
Expand Down
4 changes: 2 additions & 2 deletions src/Yarhl.UnitTests/FileFormat/BaseGeneralTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public abstract class BaseGeneralTests<T>
[Test]
public void FormatIsFoundAndIsUnique()
{
var formats = ConvertersLocator.Instance.Formats
var formats = ConverterLocator.Instance.Formats
.Select(f => f.Type);
Assert.That(formats, Does.Contain(typeof(T)));
Assert.That(formats, Is.Unique);
Expand All @@ -41,7 +41,7 @@ public void FormatIsFoundAndIsUnique()
[Test]
public void FormatNameMatchAndIsUnique()
{
var names = ConvertersLocator.Instance.Formats
var names = ConverterLocator.Instance.Formats
.Select(f => f.Name);
Assert.That(names, Does.Contain(Name));
Assert.That(names, Is.Unique);
Expand Down
207 changes: 129 additions & 78 deletions src/Yarhl.UnitTests/Plugins/FileFormat/ConvertersLocatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,122 +23,173 @@ namespace Yarhl.UnitTests.Plugins.FileFormat;
using System.Linq;
using NUnit.Framework;
using Yarhl.FileFormat;
using Yarhl.FileSystem;
using Yarhl.IO;
using Yarhl.Plugins;
using Yarhl.Plugins.FileFormat;

[TestFixture]
public class ConvertersLocatorTests
{
/*
[Test]
public void FormatMetadataContainsNameAndType()
public void InstanceIsSingleton()
{
var format = TypeLocator.Instance.GetFormats()
.Single(p => p.Metadata.Type == typeof(StringFormat));
Assert.That(
format.Metadata.Name,
Is.EqualTo(typeof(StringFormat).FullName));
ConverterLocator instance1 = ConverterLocator.Instance;
ConverterLocator instance2 = ConverterLocator.Instance;

Assert.That(instance1, Is.SameAs(instance2));
}

[Test]
public void FormatsAreNotDuplicated()
public void InstanceIsInitialized()
{
Assert.That(
TypeLocator.Instance.GetFormats().Select(f => f.Metadata.Type),
Is.Unique);
ConverterLocator instance = ConverterLocator.Instance;

Assert.That(instance.Formats, Is.Not.Null);
Assert.That(instance.Converters, Is.Not.Null);
}

[Test]
public void GetFormatsReturnsKnownFormats()
public void LocateFormatsWithTypeInfo()
{
Assert.That(
TypeLocator.Instance.GetFormats().Select(f => f.Metadata.Name),
Does.Contain(typeof(BinaryFormat).FullName));
InterfaceImplementationInfo myFormat = ConverterLocator.Instance.Formats
.FirstOrDefault(i => i.Type == typeof(DerivedSourceFormat));

Assert.That(myFormat, Is.Not.Null);
Assert.That(myFormat.InterfaceImplemented, Is.EqualTo(typeof(IFormat)));
Assert.That(myFormat.Name, Is.EqualTo(typeof(DerivedSourceFormat).FullName));
}

[Test]
public void FormatsAreNotDuplicated()
{
InterfaceImplementationInfo[] formats = ConverterLocator.Instance.Formats
.Where(f => f.Type == typeof(MySourceFormat))
.ToArray();

Assert.That(formats, Has.Length.EqualTo(1));
}

[Test]
public void FindSingleInnerConverter()
public void LocateFormatsFindYarhlBaseFormats()
{
IConverter<string, ulong> converter = null;
Assert.That(
() => converter = TypeLocator.Instance
.FindExtensions<IConverter<string, ulong>>()
.Single(),
Throws.Nothing);
ConverterLocator.Instance.Formats.Select(f => f.Type),
Does.Contain(typeof(BinaryFormat)));

Assert.That(
converter,
Is.InstanceOf<SingleOuterConverterExample.SingleInnerConverterExample>());
Assert.That(converter.Convert("4"), Is.EqualTo(4));
ConverterLocator.Instance.Formats.Select(f => f.Type),
Does.Contain(typeof(NodeContainerFormat)));
}

[Test]
public void FindSingleOuterConverter()
public void LocateConvertersWithTypeInfo()
{
IConverter<string, uint> converter = null;
Assert.That(
() => converter = TypeLocator.Instance
.FindExtensions<IConverter<string, uint>>()
.Single(),
Throws.Nothing);
Assert.That(converter, Is.InstanceOf<SingleOuterConverterExample>());
Assert.That(converter.Convert("5"), Is.EqualTo(5));
ConverterTypeInfo result = ConverterLocator.Instance.Converters
.FirstOrDefault(i => i.Type == typeof(MyConverter));

Assert.That(result, Is.Not.Null);
Assert.That(result.InterfaceImplemented, Is.EqualTo(typeof(IConverter<MySourceFormat, MyDestFormat>)));
Assert.That(result.Name, Is.EqualTo(typeof(MyConverter).FullName));
Assert.That(result.SourceType, Is.EqualTo(typeof(MySourceFormat)));
Assert.That(result.DestinationType, Is.EqualTo(typeof(MyDestFormat)));
}

[Test]
public void FindTwoConvertersInSameClass()
public void ConvertersAreNotDuplicated()
{
var converter1 = TypeLocator.Instance
.FindExtensions<IConverter<string, int>>();
Assert.IsInstanceOf<TwoConvertersExample>(converter1.Single());
Assert.DoesNotThrow(() =>
converter1.Single(t =>
Array.Exists(t.GetType().GetInterfaces(), i =>
i.IsGenericType &&
i.GenericTypeArguments.Length == 2 &&
i.GenericTypeArguments[0] == typeof(string) &&
i.GenericTypeArguments[1] == typeof(int))));
var converter2 = TypeLocator.Instance
.FindExtensions<IConverter<int, string>>();
Assert.IsInstanceOf<TwoConvertersExample>(converter2.Single());
Assert.DoesNotThrow(() =>
converter2.Single(t =>
Array.Exists(t.GetType().GetInterfaces(), i =>
i.IsGenericType &&
i.GenericTypeArguments.Length == 2 &&
i.GenericTypeArguments[0] == typeof(int) &&
i.GenericTypeArguments[1] == typeof(string))));
ConverterTypeInfo[] results = ConverterLocator.Instance.Converters
.Where(f => f.Type == typeof(MyConverter))
.ToArray();

Assert.That(results, Has.Length.EqualTo(1));
}

[Test]
public void FindDerivedConverter()
public void ScanAssembliesDoesNotDuplicateFindings()
{
var converters = TypeLocator.Instance
.FindExtensions<IConverter<string, long>>();
IConverter<string, long> converter = null;
Assert.That(
() => converter = converters.Single(),
Throws.Nothing);
Assert.IsInstanceOf<DerivedConverter>(converter);
Assert.IsInstanceOf<BaseAbstractConverter>(converter);
Assert.That(converter.Convert("3"), Is.EqualTo(3));
ConverterLocator.Instance.ScanAssemblies();

FormatsAreNotDuplicated();
ConvertersAreNotDuplicated();
}

[Test]
public void LocateConverterWithParameters()
{
ConverterTypeInfo[] results = ConverterLocator.Instance.Converters
.Where(f => f.Type == typeof(MyConverterParametrized))
.ToArray();

Assert.That(results.Length, Is.EqualTo(1));
}

[Test]
public void FindConvertsWithOtherInterfaces()
public void LocateSingleInnerConverter()
{
IConverter<string, short> converter = null;
ConverterTypeInfo converter = ConverterLocator.Instance.Converters
.FirstOrDefault(c => c.Type == typeof(SingleOuterConverter.SingleInnerConverter));

Assert.That(converter, Is.Not.Null);
}

[Test]
public void LocateSingleOuterConverter()
{
ConverterTypeInfo converter = ConverterLocator.Instance.Converters
.FirstOrDefault(c => c.Type == typeof(SingleOuterConverter));

Assert.That(converter, Is.Not.Null);
}

[Test]
public void LocateTwoConvertersInSameClass()
{
ConverterTypeInfo[] converters = ConverterLocator.Instance.Converters
.Where(c => c.Type == typeof(TwoConverters))
.ToArray();

Assert.That(converters.Length, Is.EqualTo(2));
Assert.That(
Array.Exists(
converters,
c => c.InterfaceImplemented == typeof(IConverter<MySourceFormat, MyDestFormat>)),
Is.True);
Assert.That(
() => converter = TypeLocator.Instance
.FindExtensions<IConverter<string, short>>()
.Single(),
Throws.Nothing);
Assert.That(converter, Is.InstanceOf<ConverterAndOtherInterface>());
Assert.That(converter.Convert("3"), Is.EqualTo(3));
Array.Exists(
converters,
c => c.SourceType == typeof(MySourceFormat) && c.DestinationType == typeof(MyDestFormat)),
Is.True);

Assert.That(
Array.Exists(
converters,
c => c.InterfaceImplemented == typeof(IConverter<MyDestFormat, MySourceFormat>)),
Is.True);
Assert.That(
((ConverterAndOtherInterface)converter).Dispose,
Throws.Nothing);
Array.Exists(
converters,
c => c.SourceType == typeof(MyDestFormat) && c.DestinationType == typeof(MySourceFormat)),
Is.True);
}

[Test]
public void LocateDerivedConverter()
{
ConverterTypeInfo[] converters = ConverterLocator.Instance.Converters
.Where(c => c.Type == typeof(DerivedConverter))
.ToArray();

Assert.That(converters.Length, Is.EqualTo(1));
}

[Test]
public void LocateConvertsWithOtherInterfaces()
{
ConverterTypeInfo[] converters = ConverterLocator.Instance.Converters
.Where(c => c.Type == typeof(ConverterAndOtherInterface))
.ToArray();

Assert.That(converters.Length, Is.EqualTo(1));
}
*/
}
Loading

0 comments on commit 1716416

Please sign in to comment.