mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Moved the private classes to separate files. Removed the FlagsHelper class and only take what we need. Some refactoring in some of the new classes.af/merge-core
23 changed files with 251 additions and 413 deletions
@ -0,0 +1,32 @@ |
|||||
|
// <copyright file="TestBase.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Tests |
||||
|
{ |
||||
|
using System.IO; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The test base class.
|
||||
|
/// </summary>
|
||||
|
public abstract class TestBase |
||||
|
{ |
||||
|
protected string CreateOutputDirectory(string path, params string[] pathParts) |
||||
|
{ |
||||
|
path = Path.Combine("TestOutput", path); |
||||
|
|
||||
|
if (pathParts != null && pathParts.Length > 0) |
||||
|
{ |
||||
|
path = Path.Combine(path, Path.Combine(pathParts)); |
||||
|
} |
||||
|
|
||||
|
if (!Directory.Exists(path)) |
||||
|
{ |
||||
|
Directory.CreateDirectory(path); |
||||
|
} |
||||
|
|
||||
|
return path; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
// <copyright file="EnumHelper.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Tests |
||||
|
{ |
||||
|
using System; |
||||
|
|
||||
|
public class EnumHelper |
||||
|
{ |
||||
|
public static T[] GetSortedValues<T>() |
||||
|
{ |
||||
|
T[] vals = (T[])Enum.GetValues(typeof(T)); |
||||
|
Array.Sort(vals); |
||||
|
return vals; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
// <copyright file="ImageFactory.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Tests |
||||
|
{ |
||||
|
public class ImageFactory : GenericFactory<Color> |
||||
|
{ |
||||
|
public override Image<Color> CreateImage(byte[] bytes) => new Image(bytes); |
||||
|
|
||||
|
public override Image<Color> CreateImage(int width, int height) => new Image(width, height); |
||||
|
} |
||||
|
} |
||||
@ -1,242 +0,0 @@ |
|||||
// <copyright file="FlagsHelper.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
namespace ImageSharp.Tests |
|
||||
{ |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Text; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Helper class for flag manipulation, based on
|
|
||||
/// <see>
|
|
||||
/// <cref>http://www.codeproject.com/KB/dotnet/enum.aspx</cref>
|
|
||||
/// </see>
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">Must be enum type (declared using <c>enum</c> keyword)</typeparam>
|
|
||||
public class FlagsHelper<T> |
|
||||
where T : struct, IConvertible |
|
||||
{ |
|
||||
private static readonly EnumConverter Converter; |
|
||||
|
|
||||
static FlagsHelper() |
|
||||
{ |
|
||||
Type type = typeof(T); |
|
||||
string[] names = Enum.GetNames(type); |
|
||||
var values = (T[])Enum.GetValues(type); |
|
||||
|
|
||||
Converter = new FlagsEnumConverter(names, values); |
|
||||
} |
|
||||
|
|
||||
public static T[] GetSortedValues() |
|
||||
{ |
|
||||
T[] vals = (T[])Enum.GetValues(typeof(T)); |
|
||||
Array.Sort(vals); |
|
||||
return vals; |
|
||||
} |
|
||||
|
|
||||
public static T Parse(string value, bool ignoreCase = false, bool parseNumeric = true) |
|
||||
{ |
|
||||
return (T)Enum.ToObject(typeof(T), Converter.ParseInternal(value, ignoreCase, parseNumeric)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts enum value to string
|
|
||||
/// </summary>
|
|
||||
/// <param name="value">Enum value converted to int</param>
|
|
||||
/// <returns>If <paramref name="value"/> is defined, the enum member name; otherwise the string representation of the <paramref name="value"/>.
|
|
||||
/// If <see cref="FlagsAttribute"/> is applied, can return comma-separated list of values</returns>
|
|
||||
public static string ToString(int value) |
|
||||
{ |
|
||||
return Converter.ToStringInternal(value); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts enum value to string
|
|
||||
/// </summary>
|
|
||||
/// <param name="value">Enum value</param>
|
|
||||
/// <returns>If <paramref name="value"/> is defined, the enum member name; otherwise the string representation of the <paramref name="value"/>.
|
|
||||
/// If <see cref="FlagsAttribute"/> is applied, can return comma-separated list of values</returns>
|
|
||||
public static string ToString(T value) |
|
||||
{ |
|
||||
return Converter.ToStringInternal(value.ToInt32(null)); |
|
||||
} |
|
||||
|
|
||||
public static bool TryParse(string value, bool ignoreCase, bool parseNumeric, out T result) |
|
||||
{ |
|
||||
int ir; |
|
||||
bool b = Converter.TryParseInternal(value, ignoreCase, parseNumeric, out ir); |
|
||||
result = (T)Enum.ToObject(typeof(T), ir); |
|
||||
return b; |
|
||||
} |
|
||||
|
|
||||
public static bool TryParse(string value, bool ignoreCase, out T result) |
|
||||
{ |
|
||||
int ir; |
|
||||
bool b = Converter.TryParseInternal(value, ignoreCase, true, out ir); |
|
||||
result = (T)Enum.ToObject(typeof(T), ir); |
|
||||
return b; |
|
||||
} |
|
||||
|
|
||||
public static bool TryParse(string value, out T result) |
|
||||
{ |
|
||||
int ir; |
|
||||
bool b = Converter.TryParseInternal(value, false, true, out ir); |
|
||||
result = (T)Enum.ToObject(typeof(T), ir); |
|
||||
return b; |
|
||||
} |
|
||||
|
|
||||
class DictionaryEnumConverter : EnumConverter |
|
||||
{ |
|
||||
protected readonly Dictionary<int, string> Dic; |
|
||||
|
|
||||
protected DictionaryEnumConverter(string[] names, T[] values) |
|
||||
{ |
|
||||
this.Dic = new Dictionary<int, string>(names.Length); |
|
||||
for (int j = 0; j < names.Length; j++) this.Dic.Add(Convert.ToInt32(values[j], null), names[j]); |
|
||||
} |
|
||||
|
|
||||
public override int ParseInternal(string value, bool ignoreCase, bool parseNumber) |
|
||||
{ |
|
||||
if (value == null) throw new ArgumentNullException(nameof(value)); |
|
||||
if (value.Length == 0) throw new ArgumentException("Value is empty", nameof(value)); |
|
||||
char f = value[0]; |
|
||||
if (parseNumber && (char.IsDigit(f) || f == '+' || f == '-')) return int.Parse(value); |
|
||||
StringComparison stringComparison = ignoreCase |
|
||||
? StringComparison.OrdinalIgnoreCase |
|
||||
: StringComparison.Ordinal; |
|
||||
foreach (KeyValuePair<int, string> pair in this.Dic) |
|
||||
{ |
|
||||
if (pair.Value.Equals(value, stringComparison)) return pair.Key; |
|
||||
} |
|
||||
|
|
||||
throw new ArgumentException("Enum value wasn't found", nameof(value)); |
|
||||
} |
|
||||
|
|
||||
public override string ToStringInternal(int value) |
|
||||
{ |
|
||||
string n; |
|
||||
return this.Dic.TryGetValue(value, out n) ? n : value.ToString(); |
|
||||
} |
|
||||
|
|
||||
public override bool TryParseInternal(string value, bool ignoreCase, bool parseNumber, out int result) |
|
||||
{ |
|
||||
result = 0; |
|
||||
if (string.IsNullOrEmpty(value)) return false; |
|
||||
char f = value[0]; |
|
||||
if (parseNumber && (char.IsDigit(f) || f == '+' || f == '-')) |
|
||||
{ |
|
||||
int i; |
|
||||
if (int.TryParse(value, out i)) |
|
||||
{ |
|
||||
result = i; |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
StringComparison stringComparison = ignoreCase |
|
||||
? StringComparison.OrdinalIgnoreCase |
|
||||
: StringComparison.Ordinal; |
|
||||
foreach (KeyValuePair<int, string> pair in this.Dic) |
|
||||
{ |
|
||||
if (pair.Value.Equals(value, stringComparison)) |
|
||||
{ |
|
||||
result = pair.Key; |
|
||||
return true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
abstract class EnumConverter |
|
||||
{ |
|
||||
public abstract int ParseInternal(string value, bool ignoreCase, bool parseNumber); |
|
||||
|
|
||||
public abstract string ToStringInternal(int value); |
|
||||
|
|
||||
public abstract bool TryParseInternal(string value, bool ignoreCase, bool parseNumber, out int result); |
|
||||
} |
|
||||
|
|
||||
class FlagsEnumConverter : DictionaryEnumConverter |
|
||||
{ |
|
||||
private static readonly string[] Seps = new[] { "," }; |
|
||||
|
|
||||
private readonly uint[] values; |
|
||||
|
|
||||
public FlagsEnumConverter(string[] names, T[] values) |
|
||||
: base(names, values) |
|
||||
{ |
|
||||
this.values = new uint[values.Length]; |
|
||||
for (int i = 0; i < values.Length; i++) this.values[i] = values[i].ToUInt32(null); |
|
||||
} |
|
||||
|
|
||||
public override int ParseInternal(string value, bool ignoreCase, bool parseNumber) |
|
||||
{ |
|
||||
string[] parts = value.Split(Seps, StringSplitOptions.RemoveEmptyEntries); |
|
||||
if (parts.Length == 1) return base.ParseInternal(value, ignoreCase, parseNumber); |
|
||||
int val = 0; |
|
||||
for (int i = 0; i < parts.Length; i++) |
|
||||
{ |
|
||||
string part = parts[i]; |
|
||||
int t = base.ParseInternal(part.Trim(), ignoreCase, parseNumber); |
|
||||
val |= t; |
|
||||
} |
|
||||
|
|
||||
return val; |
|
||||
} |
|
||||
|
|
||||
public override string ToStringInternal(int value) |
|
||||
{ |
|
||||
string n; |
|
||||
if (this.Dic.TryGetValue(value, out n)) return n; |
|
||||
var sb = new StringBuilder(); |
|
||||
const string sep = ", "; |
|
||||
uint uval; |
|
||||
unchecked |
|
||||
{ |
|
||||
uval = (uint)value; |
|
||||
|
|
||||
for (int i = this.values.Length - 1; i >= 0; i--) |
|
||||
{ |
|
||||
uint v = this.values[i]; |
|
||||
if (v == 0) continue; |
|
||||
if ((v & uval) == v) |
|
||||
{ |
|
||||
uval &= ~v; |
|
||||
sb.Insert(0, sep).Insert(0, this.Dic[(int)v]); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return uval == 0 && sb.Length > sep.Length ? sb.ToString(0, sb.Length - sep.Length) : value.ToString(); |
|
||||
} |
|
||||
|
|
||||
public override bool TryParseInternal(string value, bool ignoreCase, bool parseNumber, out int result) |
|
||||
{ |
|
||||
string[] parts = value.Split(Seps, StringSplitOptions.RemoveEmptyEntries); |
|
||||
if (parts.Length == 1) return base.TryParseInternal(value, ignoreCase, parseNumber, out result); |
|
||||
int val = 0; |
|
||||
for (int i = 0; i < parts.Length; i++) |
|
||||
{ |
|
||||
string part = parts[i]; |
|
||||
int t; |
|
||||
if (!base.TryParseInternal(part.Trim(), ignoreCase, parseNumber, out t)) |
|
||||
{ |
|
||||
result = 0; |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
val |= t; |
|
||||
} |
|
||||
|
|
||||
result = val; |
|
||||
return true; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,30 @@ |
|||||
|
// <copyright file="BlankProvider.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Tests |
||||
|
{ |
||||
|
using System; |
||||
|
|
||||
|
public abstract partial class TestImageProvider<TColor> |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
private class BlankProvider : TestImageProvider<TColor> |
||||
|
{ |
||||
|
public BlankProvider(int width, int height) |
||||
|
{ |
||||
|
this.Width = width; |
||||
|
this.Height = height; |
||||
|
} |
||||
|
|
||||
|
public override string SourceFileOrDescription => $"Blank{this.Width}x{this.Height}"; |
||||
|
|
||||
|
protected int Height { get; } |
||||
|
|
||||
|
protected int Width { get; } |
||||
|
|
||||
|
public override Image<TColor> GetImage() => this.Factory.CreateImage(this.Width, this.Height); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
// <copyright file="FileProvider.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Tests |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Concurrent; |
||||
|
|
||||
|
public abstract partial class TestImageProvider<TColor> |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
private class FileProvider : TestImageProvider<TColor> |
||||
|
{ |
||||
|
private static ConcurrentDictionary<string, Image<TColor>> cache = |
||||
|
new ConcurrentDictionary<string, Image<TColor>>(); |
||||
|
|
||||
|
private string filePath; |
||||
|
|
||||
|
public FileProvider(string filePath) |
||||
|
{ |
||||
|
this.filePath = filePath; |
||||
|
} |
||||
|
|
||||
|
public override string SourceFileOrDescription => this.filePath; |
||||
|
|
||||
|
public override Image<TColor> GetImage() |
||||
|
{ |
||||
|
var cachedImage = cache.GetOrAdd( |
||||
|
this.filePath, |
||||
|
fn => |
||||
|
{ |
||||
|
var testFile = TestFile.Create(this.filePath); |
||||
|
return this.Factory.CreateImage(testFile.Bytes); |
||||
|
}); |
||||
|
|
||||
|
return new Image<TColor>(cachedImage); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
// <copyright file="LambdaProvider.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Tests |
||||
|
{ |
||||
|
using System; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides <see cref="Image{TColor}" /> instances for parametric unit tests.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The pixel format of the image</typeparam>
|
||||
|
public abstract partial class TestImageProvider<TColor> |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
private class LambdaProvider : TestImageProvider<TColor> |
||||
|
{ |
||||
|
private readonly Func<GenericFactory<TColor>, Image<TColor>> creator; |
||||
|
|
||||
|
public LambdaProvider(Func<GenericFactory<TColor>, Image<TColor>> creator) |
||||
|
{ |
||||
|
this.creator = creator; |
||||
|
} |
||||
|
|
||||
|
public override Image<TColor> GetImage() => this.creator(this.Factory); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
// <copyright file="SolidProvider.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Tests |
||||
|
{ |
||||
|
using System; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides <see cref="Image{TColor}" /> instances for parametric unit tests.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The pixel format of the image</typeparam>
|
||||
|
public abstract partial class TestImageProvider<TColor> |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
private class SolidProvider : BlankProvider |
||||
|
{ |
||||
|
private readonly byte a; |
||||
|
|
||||
|
private readonly byte b; |
||||
|
|
||||
|
private readonly byte g; |
||||
|
|
||||
|
private readonly byte r; |
||||
|
|
||||
|
public SolidProvider(int width, int height, byte r, byte g, byte b, byte a) |
||||
|
: base(width, height) |
||||
|
{ |
||||
|
this.r = r; |
||||
|
this.g = g; |
||||
|
this.b = b; |
||||
|
this.a = a; |
||||
|
} |
||||
|
|
||||
|
public override string SourceFileOrDescription |
||||
|
=> $"Solid{this.Width}x{this.Height}_({this.r},{this.g},{this.b},{this.a})"; |
||||
|
|
||||
|
public override Image<TColor> GetImage() |
||||
|
{ |
||||
|
var image = base.GetImage(); |
||||
|
TColor color = default(TColor); |
||||
|
color.PackFromBytes(this.r, this.g, this.b, this.a); |
||||
|
|
||||
|
return image.Fill(color); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue