Skip to content

Commit

Permalink
#330 #337 unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dpvreony committed Jul 15, 2019
1 parent 6d94fc3 commit f502887
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 25 deletions.
42 changes: 38 additions & 4 deletions src/Splat.Tests/Platform/PlatformBitmapLoaderTests.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using Xunit;

Expand All @@ -10,16 +12,48 @@ namespace Splat.Tests.Platform
/// </summary>
public sealed class PlatformBitmapLoaderTests
{
#if !NETSTANDARD
/// <summary>
/// Check to ensure an instance is returned.
/// </summary>
[Fact]
public void Constructor_ReturnsInstance()
{
var instance = new Splat.PlatformBitmapLoader();
Assert.NotNull(instance);
}
#endif

#if ANDROID
/// <summary>
/// Checks to ensure an instance is returned.
/// Checks to ensure a dynamic assembly behaves on android.
/// </summary>
/// <remarks>
/// Introduced because of Splat #330.
/// </remarks>
[Fact]
public void GetTypesFromAssembly_ReturnsResultsOnDynamicAssembly()
{
var name = new AssemblyName("SomeRandomDynamicAssembly");
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(
name, AssemblyBuilderAccess.Run);

// can't test with a logger, as it invokes the splat init, which puts the test in a false state as it will init the platform bitmap loader
var drawableList = Splat.PlatformBitmapLoader.GetTypesFromAssembly(assemblyBuilder, null);
Assert.NotNull(drawableList);
Assert.Equal(0, drawableList.Length);
}

/// <summary>
/// Checks to ensure a list of drawable items is returned.
/// </summary>
[Fact]
public void GetDrawableList_ReturnsResults()
{
var drawableList = Splat.PlatformBitmapLoader.GetDrawableList();
Assert.NotNull(drawableList);
Assert.True(drawableList.Count > 0);
// can't test with a logger, as it invokes the splat init, which puts the test in a false state as it will init the platform bitmap loader
var drawableList = Splat.PlatformBitmapLoader.GetDrawableList(null);
Assert.NotNull(drawableList);
Assert.True(drawableList.Count > 0);
}
#endif
}
Expand Down
69 changes: 48 additions & 21 deletions src/Splat/Platforms/Android/Bitmaps/PlatformBitmapLoader.cs
Expand Up @@ -19,15 +19,13 @@ namespace Splat
/// </summary>
public class PlatformBitmapLoader : IBitmapLoader
{
private static readonly Dictionary<string, int> _drawableList;
private static readonly IFullLogger _log;
private readonly Dictionary<string, int> _drawableList;

/// <summary>
/// Initializes static members of the <see cref="PlatformBitmapLoader"/> class.
/// Initializes a new instance of the <see cref="PlatformBitmapLoader"/> class.
/// </summary>
static PlatformBitmapLoader()
public PlatformBitmapLoader()
{
_log = Locator.Current.GetService<ILogManager>().GetLogger(typeof(PlatformBitmapLoader));
_drawableList = GetDrawableList();
}

Expand Down Expand Up @@ -100,36 +98,53 @@ public IBitmap Create(float width, float height)
return Bitmap.CreateBitmap((int)width, (int)height, Bitmap.Config.Argb8888).FromNative();
}

internal static Dictionary<string, int> GetDrawableList()
internal static Dictionary<string, int> GetDrawableList(IFullLogger log)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();

return GetDrawableList(log, assemblies);
}

internal static Dictionary<string, int> GetDrawableList(
IFullLogger log,
Assembly[] assemblies)
{
// VS2019 onward
var assemblies = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(GetTypesFromAssembly)
var drawableTypes = assemblies
.SelectMany(a => GetTypesFromAssembly(a, log))
.Where(x => x.Name == "Resource" && x.GetNestedType("Drawable") != null)
.Select(x => x.GetNestedType("Drawable"))
.ToArray();

_log.Debug(() => "DrawableList. Got " + assemblies.Length + " assemblies.");
foreach (var assembly in assemblies)
if (log != null)
{
_log.Debug(() => "DrawableList Assembly: " + assembly.Name);
log.Debug(() => "DrawableList. Got " + drawableTypes.Length + " types.");
foreach (var drawableType in drawableTypes)
{
log.Debug(() => "DrawableList Type: " + drawableType.Name);
}
}

var result = assemblies
var result = drawableTypes
.SelectMany(x => x.GetFields())
.Where(x => x.FieldType == typeof(int) && x.IsLiteral)
.ToDictionary(k => k.Name, v => (int)v.GetRawConstantValue());

_log.Debug(() => "DrawableList. Got " + result.Count + " items.");
foreach (var keyValuePair in result)
if (log != null)
{
_log.Debug(() => "DrawableList Item: " + keyValuePair.Key);
log.Debug(() => "DrawableList. Got " + result.Count + " items.");
foreach (var keyValuePair in result)
{
log.Debug(() => "DrawableList Item: " + keyValuePair.Key);
}
}

return result;
}

internal static Type[] GetTypesFromAssembly(Assembly assembly)
internal static Type[] GetTypesFromAssembly(
Assembly assembly,
IFullLogger log)
{
try
{
Expand All @@ -141,15 +156,27 @@ internal static Type[] GetTypesFromAssembly(Assembly assembly)
// object for each type that was loaded and null for each type that could not
// be loaded, while the LoaderExceptions property contains an exception for
// each type that could not be loaded.
_log.Warn(e, "Exception while detecting drawing types.");

foreach (var loaderException in e.LoaderExceptions)
if (log != null)
{
_log.Warn(loaderException, "Inner Exception for detecting drawing types.");
log.Warn(e, "Exception while detecting drawing types.");

foreach (var loaderException in e.LoaderExceptions)
{
log.Warn(loaderException, "Inner Exception for detecting drawing types.");
}
}

return e.Types.Where(x => x != null).ToArray();
// null check here because mono doesn't appear to follow the MSDN documentation
// as of July 2019.
return e.Types != null
? e.Types.Where(x => x != null).ToArray()
: Array.Empty<Type>();
}
}

private Dictionary<string, int> GetDrawableList()
{
return GetDrawableList(Locator.Current.GetService<ILogManager>().GetLogger(typeof(PlatformBitmapLoader)));
}
}
}

0 comments on commit f502887

Please sign in to comment.