-
Notifications
You must be signed in to change notification settings - Fork 0
/
UnitEnumReportGenerator.cs
64 lines (53 loc) · 3.61 KB
/
UnitEnumReportGenerator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using Quantify.Repository.Enum.Validators;
using System.Linq;
using System.Reflection;
namespace Quantify.Repository.Enum.Report
{
/// <summary>
/// Generator class used to create instances of <see cref="UnitEnumReport"/> with results of the analysis of a unit enum.
/// </summary>
/// <remarks>
/// Only critical errors in a unit enum will make the instantiation of a <see cref="UnitRepository{TUnit}" /> fail. Minor things like missing or invalid <see cref="UnitAttribute"/> attributes, will not result in an error, but the enum value will be ignored instead.
/// This report generator returns a report with warnings and errors found when analysing a given unit enum. This result can be used in unit tests, to make sure that a unit enum is configurated in the correct way.
///
/// </remarks>
public class UnitEnumReportGenerator
{
/// <summary>
/// Create a analysis report for a given unit enum.
/// </summary>
/// <typeparam name="TUnit">The unit enum to analyse.</typeparam>
/// <returns>A unit enum report with the result of the analysis of the enm referenced in <typeparamref name="TUnit"/>.</returns>
/// <exception cref="GenericArgumentException"><typeparamref name="TUnit"/> is not an <code>enum</code>.</exception>
public UnitEnumReport CreateReport<TUnit>() where TUnit : struct
{
if (new GenericEnumParametersValidator().GenericParameterIsEnumType<TUnit>() == false)
throw new GenericArgumentException("The generic argument is not valid. Expected an enum.", nameof(TUnit), typeof(TUnit));
var hasValueMissingUnitAttribute = false;
var hasValueWithInvalidUnitAttribute = false;
var baseUnitHasUnitAttribute = false;
var isMissingBaseUnitAttribute = false;
var hasInvalidBaseUnitAttribute = false;
var enumType = typeof(TUnit);
var baseUnitAttribute = enumType.GetTypeInfo().GetCustomAttribute<BaseUnitAttribute>(false);
var baseUnitValueName = baseUnitAttribute == null ? null : System.Enum.GetName(enumType, baseUnitAttribute.BaseUnit);
isMissingBaseUnitAttribute = baseUnitAttribute == null;
if (baseUnitAttribute != null)
hasInvalidBaseUnitAttribute = baseUnitValueName == null;
foreach (var unitEnumValue in System.Enum.GetValues(enumType).OfType<TUnit>())
{
var unitAttribute = enumType.GetRuntimeField(System.Enum.GetName(enumType, unitEnumValue)).GetCustomAttribute<UnitAttribute>(false);
var unitIsBaseUnit = baseUnitValueName == null ? false : unitEnumValue.Equals(System.Enum.Parse(enumType, baseUnitValueName));
baseUnitHasUnitAttribute = baseUnitHasUnitAttribute || (unitIsBaseUnit && unitAttribute != null);
hasValueMissingUnitAttribute = hasValueMissingUnitAttribute || (unitIsBaseUnit == false && unitAttribute == null);
if (unitAttribute != null)
{
var canParseToDecimal = decimal.TryParse(unitAttribute.ValueInBaseUnits, out var decimalValue);
var canParseToDouble = double.TryParse(unitAttribute.ValueInBaseUnits, out var doubleValue);
hasValueWithInvalidUnitAttribute = hasValueWithInvalidUnitAttribute || canParseToDecimal == false || canParseToDouble == false;
}
}
return new UnitEnumReport(hasValueMissingUnitAttribute, hasValueWithInvalidUnitAttribute, baseUnitHasUnitAttribute, isMissingBaseUnitAttribute, hasInvalidBaseUnitAttribute);
}
}
}