using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using SabreTools.RedumpLib.Data;
using Xunit;
namespace MPF.Test.RedumpLib
{
// TODO: Add tests for string-to-enum conversion
public class ExtensionsTests
{
#region Cross-Enumeration
///
/// DiscType values that map to MediaType
///
private static readonly DiscType?[] _mappableDiscTypes = new DiscType?[]
{
DiscType.BD25,
DiscType.BD33,
DiscType.BD50,
DiscType.BD66,
DiscType.BD100,
DiscType.BD128,
DiscType.CD,
DiscType.DVD5,
DiscType.DVD9,
DiscType.GDROM,
DiscType.HDDVDSL,
DiscType.HDDVDDL,
DiscType.NintendoGameCubeGameDisc,
DiscType.NintendoWiiOpticalDiscSL,
DiscType.NintendoWiiOpticalDiscDL,
DiscType.NintendoWiiUOpticalDiscSL,
DiscType.UMDSL,
DiscType.UMDDL,
};
///
/// MediaType values that map to DiscType
///
private static readonly MediaType?[] _mappableMediaTypes = new MediaType?[]
{
MediaType.BluRay,
MediaType.CDROM,
MediaType.DVD,
MediaType.GDROM,
MediaType.HDDVD,
MediaType.NintendoGameCubeGameDisc,
MediaType.NintendoWiiOpticalDisc,
MediaType.NintendoWiiUOpticalDisc,
MediaType.UMD,
};
///
/// Check that every supported system has some set of MediaTypes supported
///
/// RedumpSystem value to check
[Theory]
[MemberData(nameof(GenerateRedumpSystemMappingTestData))]
public void MediaTypesTest(RedumpSystem? redumpSystem)
{
var actual = redumpSystem.MediaTypes();
Assert.NotEmpty(actual);
}
///
/// Check that both mappable and unmappable media types output correctly
///
/// MediaType value to check
/// True to expect a null mapping, false otherwise
[Theory]
[MemberData(nameof(GenerateMediaTypeMappingTestData))]
public void ToDiscTypeTest(MediaType? mediaType, bool expectNull)
{
DiscType? actual = mediaType.ToDiscType();
Assert.Equal(expectNull, actual == null);
}
///
/// Check that DiscType values all map to something appropriate
///
/// DiscType value to check
/// True to expect a null mapping, false otherwise
[Theory]
[MemberData(nameof(GenerateDiscTypeMappingTestData))]
public void ToMediaTypeTest(DiscType? discType, bool expectNull)
{
MediaType? actual = discType.ToMediaType();
Assert.Equal(expectNull, actual == null);
}
///
/// Generate a test set of DiscType values
///
/// MemberData-compatible list of DiscType values
public static List GenerateDiscTypeMappingTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (DiscType? discType in Enum.GetValues(typeof(DiscType)))
{
if (_mappableDiscTypes.Contains(discType))
testData.Add(new object[] { discType, false });
else
testData.Add(new object[] { discType, true });
}
return testData;
}
///
/// Generate a test set of RedumpSystem values
///
/// MemberData-compatible list of RedumpSystem values
public static List GenerateRedumpSystemMappingTestData()
{
var testData = new List() { new object[] { null } };
foreach (RedumpSystem? redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
{
testData.Add(new object[] { redumpSystem });
}
return testData;
}
///
/// Generate a test set of mappable media types
///
/// MemberData-compatible list of MediaTypes
public static List GenerateMediaTypeMappingTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (MediaType? mediaType in Enum.GetValues(typeof(MediaType)))
{
if (_mappableMediaTypes.Contains(mediaType))
testData.Add(new object[] { mediaType, false });
else
testData.Add(new object[] { mediaType, true });
}
return testData;
}
#endregion
#region Disc Category
///
/// Check that every DiscCategory has a long name provided
///
/// DiscCategory value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateDiscCategoryTestData))]
public void DiscCategoryLongNameTest(DiscCategory? discCategory, bool expectNull)
{
string actual = discCategory.LongName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Generate a test set of DiscCategory values
///
/// MemberData-compatible list of DiscCategory values
public static List GenerateDiscCategoryTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (DiscCategory? discCategory in Enum.GetValues(typeof(DiscCategory)))
{
testData.Add(new object[] { discCategory, false });
}
return testData;
}
#endregion
#region Disc Type
///
/// Check that every DiscType has a long name provided
///
/// DiscType value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateDiscTypeTestData))]
public void DiscTypeLongNameTest(DiscType? discType, bool expectNull)
{
string actual = discType.LongName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Generate a test set of DiscType values
///
/// MemberData-compatible list of DiscType values
public static List GenerateDiscTypeTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (DiscType? discType in Enum.GetValues(typeof(DiscType)))
{
if (discType == DiscType.NONE)
testData.Add(new object[] { discType, true });
else
testData.Add(new object[] { discType, false });
}
return testData;
}
#endregion
#region Language
///
/// Check that every Language has a long name provided
///
/// Language value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateLanguageTestData))]
public void LanguageLongNameTest(Language? language, bool expectNull)
{
string actual = language.LongName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Check that every Language has a short name provided
///
/// Language value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateLanguageTestData))]
public void LanguageShortNameTest(Language? language, bool expectNull)
{
string actual = language.ShortName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Ensure that every Language that has an ISO 639-1 code is unique
///
[Fact]
public void LanguageNoDuplicateTwoLetterCodeTest()
{
var fullLanguages = Enum.GetValues(typeof(Language)).Cast().ToList();
var filteredLanguages = new Dictionary();
int totalCount = 0;
foreach (Language? language in fullLanguages)
{
string code = language.TwoLetterCode();
if (string.IsNullOrWhiteSpace(code))
continue;
// Throw if the code already exists
if (filteredLanguages.ContainsKey(code))
throw new DuplicateNameException($"Code {code} already in dictionary");
filteredLanguages[code] = language;
totalCount++;
}
Assert.Equal(totalCount, filteredLanguages.Count);
}
///
/// Ensure that every Language that has a standard/bibliographic ISO 639-2 code is unique
///
[Fact]
public void LanguageNoDuplicateThreeLetterCodeTest()
{
var fullLanguages = Enum.GetValues(typeof(Language)).Cast().ToList();
var filteredLanguages = new Dictionary();
int totalCount = 0;
foreach (Language? language in fullLanguages)
{
string code = language.ThreeLetterCode();
if (string.IsNullOrWhiteSpace(code))
continue;
// Throw if the code already exists
if (filteredLanguages.ContainsKey(code))
throw new DuplicateNameException($"Code {code} already in dictionary");
filteredLanguages[code] = language;
totalCount++;
}
Assert.Equal(totalCount, filteredLanguages.Count);
}
///
/// Ensure that every Language that has a terminology ISO 639-2 code is unique
///
[Fact]
public void LanguageNoDuplicateThreeLetterCodeAltTest()
{
var fullLanguages = Enum.GetValues(typeof(Language)).Cast().ToList();
var filteredLanguages = new Dictionary();
int totalCount = 0;
foreach (Language? language in fullLanguages)
{
string code = language.ThreeLetterCodeAlt();
if (string.IsNullOrWhiteSpace(code))
continue;
// Throw if the code already exists
if (filteredLanguages.ContainsKey(code))
throw new DuplicateNameException($"Code {code} already in dictionary");
filteredLanguages[code] = language;
totalCount++;
}
Assert.Equal(totalCount, filteredLanguages.Count);
}
///
/// Generate a test set of Language values
///
/// MemberData-compatible list of Language values
public static List GenerateLanguageTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (Language? language in Enum.GetValues(typeof(Language)))
{
testData.Add(new object[] { language, false });
}
return testData;
}
#endregion
#region Language Selection
///
/// Check that every LanguageSelection has a long name provided
///
/// LanguageSelection value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateLanguageSelectionTestData))]
public void LanguageSelectionLongNameTest(LanguageSelection? languageSelection, bool expectNull)
{
string actual = languageSelection.LongName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Generate a test set of LanguageSelection values
///
/// MemberData-compatible list of LanguageSelection values
public static List GenerateLanguageSelectionTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (LanguageSelection? languageSelection in Enum.GetValues(typeof(LanguageSelection)))
{
testData.Add(new object[] { languageSelection, false });
}
return testData;
}
#endregion
#region Media Type
///
/// Check that every MediaType has a long name provided
///
/// MediaType value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateMediaTypeTestData))]
public void MediaTypeLongNameTest(MediaType? mediaType, bool expectNull)
{
string actual = mediaType.LongName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Check that every MediaType has a short name provided
///
/// MediaType value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateMediaTypeTestData))]
public void MediaTypeShortNameTest(MediaType? mediaType, bool expectNull)
{
string actual = mediaType.ShortName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Generate a test set of MediaType values
///
/// MemberData-compatible list of MediaType values
public static List GenerateMediaTypeTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (MediaType? mediaType in Enum.GetValues(typeof(MediaType)))
{
testData.Add(new object[] { mediaType, false });
}
return testData;
}
#endregion
#region Region
///
/// Check that every Region has a long name provided
///
/// Region value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateRegionTestData))]
public void RegionLongNameTest(Region? region, bool expectNull)
{
string actual = region.LongName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Check that every Region has a short name provided
///
/// Region value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateRegionTestData))]
public void RegionShortNameTest(Region? region, bool expectNull)
{
string actual = region.ShortName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Ensure that every Language that has an ISO 639-1 code is unique
///
[Fact]
public void RegionNoDuplicateShortNameTest()
{
var fullRegions = Enum.GetValues(typeof(Region)).Cast().ToList();
var filteredRegions = new Dictionary();
int totalCount = 0;
foreach (Region? region in fullRegions)
{
string code = region.ShortName();
if (string.IsNullOrWhiteSpace(code))
continue;
// Throw if the code already exists
if (filteredRegions.ContainsKey(code))
throw new DuplicateNameException($"Code {code} already in dictionary");
filteredRegions[code] = region;
totalCount++;
}
Assert.Equal(totalCount, filteredRegions.Count);
}
///
/// Generate a test set of Region values
///
/// MemberData-compatible list of Region values
public static List GenerateRegionTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (Region? region in Enum.GetValues(typeof(Region)))
{
testData.Add(new object[] { region, false });
}
return testData;
}
#endregion
#region Site Code
///
/// Check that every SiteCode has a long name provided
///
/// SiteCode value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateSiteCodeTestData))]
public void SiteCodeLongNameTest(SiteCode? siteCode, bool expectNull)
{
string actual = siteCode.LongName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Check that every SiteCode has a short name provided
///
/// SiteCode value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateSiteCodeTestData))]
public void SiteCodeShortNameTest(SiteCode? siteCode, bool expectNull)
{
string actual = siteCode.ShortName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Generate a test set of SiteCode values
///
/// MemberData-compatible list of SiteCode values
public static List GenerateSiteCodeTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (SiteCode? siteCode in Enum.GetValues(typeof(SiteCode)))
{
testData.Add(new object[] { siteCode, false });
}
return testData;
}
#endregion
#region System
///
/// Check that every RedumpSystem has a long name provided
///
/// RedumpSystem value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateRedumpSystemTestData))]
public void RedumpSystemLongNameTest(RedumpSystem? redumpSystem, bool expectNull)
{
string actual = redumpSystem.LongName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
// TODO: Re-enable the following test once non-Redump systems are accounted for
///
/// Check that every RedumpSystem has a short name provided
///
/// RedumpSystem value to check
/// True to expect a null value, false otherwise
//[Theory]
//[MemberData(nameof(GenerateRedumpSystemTestData))]
//public void RedumpSystemShortNameTest(RedumpSystem? redumpSystem, bool expectNull)
//{
// string actual = redumpSystem.ShortName();
// if (expectNull)
// Assert.Null(actual);
// else
// Assert.NotNull(actual);
//}
// TODO: Test the other attributes as well
// Most are bool checks so they're not as interesting to have unit tests around
// SystemCategory always returns something as well, so is it worth testing?
///
/// Generate a test set of RedumpSystem values
///
/// MemberData-compatible list of RedumpSystem values
public static List GenerateRedumpSystemTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (RedumpSystem? redumpSystem in Enum.GetValues(typeof(RedumpSystem)))
{
// We want to skip all markers for this
if (redumpSystem.IsMarker())
continue;
testData.Add(new object[] { redumpSystem, false });
}
return testData;
}
#endregion
#region System Category
///
/// Check that every SystemCategory has a long name provided
///
/// SystemCategory value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateSystemCategoryTestData))]
public void SystemCategoryLongNameTest(SystemCategory? systemCategory, bool expectNull)
{
string actual = systemCategory.LongName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Generate a test set of SystemCategory values
///
/// MemberData-compatible list of SystemCategory values
public static List GenerateSystemCategoryTestData()
{
var testData = new List() { new object[] { null, true } };
foreach (SystemCategory? systemCategory in Enum.GetValues(typeof(SystemCategory)))
{
if (systemCategory == SystemCategory.NONE)
testData.Add(new object[] { systemCategory, true });
else
testData.Add(new object[] { systemCategory, false });
}
return testData;
}
#endregion
#region Yes/No
///
/// Check that every YesNo has a long name provided
///
/// YesNo value to check
/// True to expect a null value, false otherwise
[Theory]
[MemberData(nameof(GenerateYesNoTestData))]
public void YesNoLongNameTest(YesNo? yesNo, bool expectNull)
{
string actual = yesNo.LongName();
if (expectNull)
Assert.Null(actual);
else
Assert.NotNull(actual);
}
///
/// Generate a test set of YesNo values
///
/// MemberData-compatible list of YesNo values
public static List GenerateYesNoTestData()
{
var testData = new List() { new object[] { null, false } };
foreach (YesNo? yesNo in Enum.GetValues(typeof(YesNo)))
{
testData.Add(new object[] { yesNo, false });
}
return testData;
}
#endregion
}
}