Upgrade to .NET 4.7 & C# 7.3 + Changes

- Now using the latest .NET version (4.7) & the latest C# version (7.3)
- Replaced old data conversion methods with new extension methods
- Created a unit test project & the first tests (more to come at a later date)
This commit is contained in:
Cuyler36 2018-08-13 00:49:35 -04:00
parent 1519cbbd42
commit 4c02941970
14 changed files with 285 additions and 123 deletions

1
.gitignore vendored
View file

@ -9,3 +9,4 @@ bin/
obj/
*.DotSettings
*.user
packages/

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
@ -7,7 +7,7 @@
<OutputType>WinExe</OutputType>
<NoStandardLibraries>false</NoStandardLibraries>
<AssemblyName>ACSE</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
@ -41,6 +41,7 @@
<OutputPath>bin\Debug\</OutputPath>
<NoWarn>IDE1006</NoWarn>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -4860,6 +4861,7 @@
<Compile Include="Classes\Emotion.cs" />
<Compile Include="Classes\Extensions\ArrayExtensions.cs" />
<Compile Include="Classes\Extensions\ControlExtensions.cs" />
<Compile Include="Classes\Extensions\DataExtensions.cs" />
<Compile Include="Classes\Extensions\LinqExtensions.cs" />
<Compile Include="Classes\Extensions\PointExtension.cs" />
<Compile Include="Classes\Generators\Generator.cs" />
@ -4949,7 +4951,6 @@
<DependentUpon>AboutBox.cs</DependentUpon>
</Compile>
<Compile Include="Classes\Checksum.cs" />
<Compile Include="Classes\DataConverter.cs" />
<Compile Include="Classes\House\HouseData.cs" />
<Compile Include="Classes\Inventory.cs" />
<Compile Include="Classes\Item\ItemData.cs" />
@ -5025,6 +5026,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include=".git\" />
<Folder Include="Tests\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSHARP.Targets" />
<ProjectExtensions>

View file

@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.27703.2026
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ACSE", "ACSE.csproj", "{078BA400-42DD-432A-9844-32213157A29D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ACSE.Tests", "Tests\ACSE.Tests\ACSE.Tests.csproj", "{A230992E-9ECB-4A07-9438-2551854A6578}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -21,6 +23,14 @@ Global
{078BA400-42DD-432A-9844-32213157A29D}.Release|Any CPU.Build.0 = Release|Any CPU
{078BA400-42DD-432A-9844-32213157A29D}.Release|x86.ActiveCfg = Release|x86
{078BA400-42DD-432A-9844-32213157A29D}.Release|x86.Build.0 = Release|x86
{A230992E-9ECB-4A07-9438-2551854A6578}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A230992E-9ECB-4A07-9438-2551854A6578}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A230992E-9ECB-4A07-9438-2551854A6578}.Debug|x86.ActiveCfg = Debug|Any CPU
{A230992E-9ECB-4A07-9438-2551854A6578}.Debug|x86.Build.0 = Debug|Any CPU
{A230992E-9ECB-4A07-9438-2551854A6578}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A230992E-9ECB-4A07-9438-2551854A6578}.Release|Any CPU.Build.0 = Release|Any CPU
{A230992E-9ECB-4A07-9438-2551854A6578}.Release|x86.ActiveCfg = Release|Any CPU
{A230992E-9ECB-4A07-9438-2551854A6578}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -2,12 +2,12 @@
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="ACSE.ItemColorSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="ACSE.ItemColorSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
<section name="ACSE.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/>
</startup>
<userSettings>
<ACSE.ItemColorSettings>

View file

@ -51,7 +51,7 @@ public WorldAcre(ushort acreId, int position, ushort[] items = null, byte[] buri
public WorldAcre(ushort acreId, int position) : base(acreId, position) { }
public WorldAcre(ushort acreId, int position, uint[] items = null, byte[] burriedItemData = null, SaveType saveType = SaveType.AnimalCrossing)
public WorldAcre(ushort acreId, int position, uint[] items = null, byte[] buriedItemData = null, SaveType saveType = SaveType.AnimalCrossing)
: this(acreId, position, null, null, saveType, items) { }
public WorldAcre(ushort acreId, int position, WorldItem[] items, byte[] buriedItemData = null, SaveType saveType = SaveType.AnimalCrossing, int townPosition = -1) : base(acreId, position)
@ -81,39 +81,26 @@ private static int GetBuriedDataLocation(WorldItem item, int acre, SaveType save
return worldPosition / 8;
}
public void SetBuriedInMemory(WorldItem item, int acre, byte[] burriedItemData, bool buried, SaveType saveType)
public void SetBuriedInMemory(WorldItem item, int acre, byte[] buriedItemData, bool buried, SaveType saveType)
{
if (saveType == SaveType.NewLeaf || saveType == SaveType.WelcomeAmiibo) return;
var buriedLocation = GetBuriedDataLocation(item, acre, saveType);
if (buriedLocation > -1)
{
DataConverter.SetBit(ref burriedItemData[buriedLocation], item.Location.X % 8, buried);
item.Buried = DataConverter.ToBit(burriedItemData[buriedLocation], item.Location.X % 8) == 1;
}
else
item.Buried = false;
}
//Correct decoding/setting of buried items. Fixes the hacky SaveType case for AC/CF. (Don't forget to implement this!)
private void SetBuriedInMemoryFixed(WorldItem item, int acre, ushort[] buriedItemData, bool buried, SaveType saveType)
{
if (saveType == SaveType.NewLeaf || saveType == SaveType.WelcomeAmiibo) return;
var buriedLocation = (acre * 256 + item.Index) / 16;
if (buriedLocation > -1)
{
var buriedRowBytes = BitConverter.GetBytes(buriedItemData[buriedLocation]);
DataConverter.SetBit(ref buriedRowBytes[item.Location.X / 8], item.Location.X % 8, buried); //Should probably rewrite bit editing functions to take any data type
item.Buried = DataConverter.ToBit(buriedRowBytes[item.Location.X / 8], item.Location.X % 8) == 1;
buriedItemData[buriedLocation] = BitConverter.ToUInt16(buriedRowBytes, 0);
buriedItemData[buriedLocation].SetBit(item.Location.X % 8, buried);
item.Buried = buriedItemData[buriedLocation].GetBit(item.Location.X % 8) == 1;
}
else
item.Buried = false;
}
private static void SetBuried(WorldItem item, int acre, byte[] burriedItemData, SaveType saveType)
private static void SetBuried(WorldItem item, int acre, byte[] buriedItemData, SaveType saveType)
{
var burriedDataOffset = GetBuriedDataLocation(item, acre, saveType);
if (burriedDataOffset > -1 && burriedDataOffset < burriedItemData.Length)
item.Buried = DataConverter.ToBit(burriedItemData[burriedDataOffset], item.Location.X % 8) == 1;
if (burriedDataOffset > -1 && burriedDataOffset < buriedItemData.Length)
{
item.Buried = buriedItemData[burriedDataOffset].GetBit(item.Location.X % 8) == 1;
}
}
/// <summary>

View file

@ -1,75 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections;
namespace ACSE
{
public static class DataConverter
{
private static byte ConvertByte(BitArray b)
{
byte value = 0;
for (byte i = 0; i < b.Count; i++)
if (b[i])
value |= (byte)(1 << i);
return value;
}
public static Dictionary<Type, Delegate> TypeMap = new Dictionary<Type, Delegate>
{
{typeof(byte[]), new Func<byte[], byte>
(b => ConvertByte(new BitArray(b)))
},
{typeof(BitArray), new Func<BitArray, byte>
(ConvertByte)
}
};
public static byte[] ToBits(byte[] byteBuffer, bool reverse = false)
{
var bits = new byte[8 * byteBuffer.Length];
for (var i = 0; i < byteBuffer.Length; i++)
{
var bitArray = new BitArray(new[] { byteBuffer[i] });
for (var x = 0; x < bitArray.Length; x++)
bits[i * 8 + (reverse ? 7 - x : x)] = Convert.ToByte(bitArray[x]);
}
return bits;
}
public static byte ToBit(byte bitByte, int bitIndex, bool reverse = false)
{
return (byte)((reverse ? bitByte >> (7 - bitIndex) : bitByte >> bitIndex) & 1);
}
public static void SetBit(ref byte bitByte, int bitIndex, bool set, bool reverse = false)
{
var mask = 1 << (reverse ? 7 - bitIndex : bitIndex);
if (set)
bitByte |= (byte)mask;
else
bitByte &= (byte)~mask;
}
public static byte ToByte(object variant)
{
return (byte)TypeMap[variant.GetType()].DynamicInvoke(variant);
}
public static byte GetByte(byte[] bits)
{
byte value = 0;
for (var i = 0; i < 8; i++)
value |= (byte)((bits[i] & 1) << i);
return value;
}
public static byte[] GetBits(byte value)
{
var bits = new byte[8];
for (var i = 0; i < 8; i++)
bits[i] = (byte)((value >> i) & 1);
return bits;
}
}
}

View file

@ -0,0 +1,90 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
namespace System
{
public static class DataExtensions
{
/// <summary>
/// Returns a tuple containing the two nibbles of the byte.
/// </summary>
/// <param name="b">The input byte</param>
/// <returns>The byte's nibbles</returns>
public static (byte, byte) GetNibbles(this byte b)
{
return ((byte)(b & 0x0F), (byte)((b >> 4) & 0x0F));
}
/// <summary>
/// Returns the bit from a specified index of a byte.
/// </summary>
/// <param name="b">The input byte</param>
/// <param name="index">The bit to retrieve</param>
/// <param name="reverse">Sets if the index should be reversed</param>
/// <returns>The requested bit</returns>
public static byte GetBit(this byte b, int index, bool reverse = false)
{
if (index < 0 || index > 7) throw new ArgumentException("Index is expected to be in the range of 0 - 7!");
return (byte)((reverse ? b >> (7 - index) : b >> index) & 1);
}
/// <summary>
/// Returns a list of bits for any ValueType object supplied that isn't a struct.
/// </summary>
/// <param name="input">The input object</param>
/// <returns><see cref="Collections.ICollection"/> of bits</returns>
public static ICollection<byte> GetBits(this ValueType input)
{
if (!input.GetType().IsPrimitive) throw new ArgumentException("Object cannot be a struct!");
var bits = Marshal.SizeOf(input) * 8;
var output = new byte[bits];
dynamic obj = input;
for (var i = 0; i < bits; i++)
{
output[i] = (byte)((obj >> i) & 1);
}
return output;
}
/// <summary>
/// Sets a specified bit of a byte.
/// </summary>
/// <param name="b">The byte to modify</param>
/// <param name="index">The index of the bit to set</param>
/// <param name="set">Should the bit be set or not</param>
/// <param name="reverse">Is the index reversed (e.g. 0 = topmost bit)</param>
public static void SetBit(ref this byte b, int index, bool set, bool reverse = false)
{
if (index < 0 || index > 7) throw new ArgumentException("Index is expected to be in the range of 0 - 7!");
var bitmask = 1 << (reverse ? 7 - index : index);
if (set)
{
b |= (byte) bitmask;
}
else
{
b &= (byte) ~bitmask;
}
}
/// <summary>
/// Creates a byte from an <see cref="IEnumerable{T}"/>. If less than 8 entries are supplied, 0 will be used for the remaining bits.
/// </summary>
/// <param name="byteArray">The <see cref="IEnumerable{T}"/> to create the byte from</param>
/// <returns>The created byte</returns>
public static byte GetByte(this IEnumerable<byte> byteArray)
{
var bitArray = byteArray as byte[] ?? byteArray.ToArray();
byte val = 0;
for (var i = 0; i < (bitArray.Length >= 8 ? 8 : bitArray.Length); i++)
{
val |= (byte)((bitArray[i] & 1) << i);
}
return val;
}
}
}

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace ACSE
{
@ -182,25 +183,27 @@ private static int GetBuriedDataLocation(WorldItem item, int acre, SaveType save
return worldPosition / 8;
}
private static void SetBuried(WorldItem item, int acre, IReadOnlyList<byte> burriedItemData, SaveType saveType)
private static void SetBuried(WorldItem item, int acre, IReadOnlyList<byte> buriedItemData, SaveType saveType)
{
var burriedDataOffset = GetBuriedDataLocation(item, acre, saveType);
if (burriedDataOffset > -1 && burriedDataOffset < burriedItemData.Count)
item.Buried = DataConverter.ToBit(burriedItemData[burriedDataOffset], item.Location.X % 8) == 1;
if (burriedDataOffset > -1 && burriedDataOffset < buriedItemData.Count)
{
item.Buried = buriedItemData[burriedDataOffset].GetBit(item.Location.X % 8) == 1;
}
}
// TODO: Make a toggle to enable/disable the island.
private bool IsPurchased()
=> (_saveFile.ReadByte(_offset + IslandInfoFlag) & 0x80) == 0x80;
public void SetBuriedInMemory(WorldItem item, int acre, byte[] burriedItemData, bool buried, SaveType saveType)
public void SetBuriedInMemory(WorldItem item, int acre, byte[] buriedItemData, bool buried, SaveType saveType)
{
if (saveType == SaveType.NewLeaf || saveType == SaveType.WelcomeAmiibo) return;
var buriedLocation = GetBuriedDataLocation(item, acre, saveType);
if (buriedLocation > -1)
{
DataConverter.SetBit(ref burriedItemData[buriedLocation], item.Location.X % 8, buried);
item.Buried = DataConverter.ToBit(burriedItemData[buriedLocation], item.Location.X % 8) == 1;
buriedItemData[buriedLocation].SetBit(item.Location.X % 8, buried);
item.Buried = buriedItemData[buriedLocation].GetBit(item.Location.X % 8) == 1;
}
else
item.Buried = false;

View file

@ -1,4 +1,5 @@
using System.Drawing;
using System;
using System.Drawing;
namespace ACSE
{
@ -307,8 +308,13 @@ public Building(byte id, byte x, byte y, SaveType saveType)
//Upper Nibble = Acre
//Lower Nibble = Position in Acre
//I say this, as a town hall in New Leaf with location bytes of X = 0x28, Y = 0x19 is positioned on the third X acre and second Y acre at 0x8, 0x9.
SaveDataManager.GetNibbles(x, out XPos, out AcreX);
SaveDataManager.GetNibbles(y, out YPos, out AcreY);
var (xpos, acrex) = x.GetNibbles();
var (ypos, acrey) = y.GetNibbles();
XPos = xpos;
AcreX = acrex;
YPos = ypos;
AcreY = acrey;
AcreIndex = (byte)((AcreY - 1) * 5 + (AcreX - 1)); // * 5 works here because both CF and NL use 5 X acres
if (AcreIndex > 24) //Works for NL too, since the dock is located in the 5th Y acre row.
AcreIndex = 0;

View file

@ -1046,16 +1046,5 @@ public static Dictionary<string, Dictionary<ushort, string>> GetFiledAcreDataUIn
return filedList;
}
public static void GetNibbles(byte byteToSplit, out byte lowerNibble, out byte upperNibble)
{
lowerNibble = (byte)(byteToSplit & 0x0F);
upperNibble = (byte)((byteToSplit & 0xF0) >> 4);
}
public static byte CondenseNibbles(byte lowerNibble, byte upperNibble)
{
return (byte)(((upperNibble & 0x0F) << 4) + lowerNibble & 0x0F);
}
}
}

View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A230992E-9ECB-4A07-9438-2551854A6578}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ACSE.Tests</RootNamespace>
<AssemblyName>ACSE.Tests</AssemblyName>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\MSTest.TestFramework.1.2.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\MSTest.TestFramework.1.2.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="UtilityTests\ExtensionTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ACSE.csproj">
<Project>{078ba400-42dd-432a-9844-32213157a29d}</Project>
<Name>ACSE</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props'))" />
<Error Condition="!Exists('..\..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets'))" />
</Target>
<Import Project="..\..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets')" />
</Project>

View file

@ -0,0 +1,20 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("ACSE.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ACSE.Tests")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("a230992e-9ecb-4a07-9438-2551854a6578")]
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,50 @@
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ACSE.Tests.UtilityTests
{
[TestClass]
public class ExtensionTests
{
[TestMethod]
public void TestSetBit()
{
byte test = 0xF;
test.SetBit(4, true);
Assert.AreEqual(test, 0x1F);
}
[TestMethod]
public void TestGetBit()
{
const byte test = 0x02;
Assert.AreEqual(test.GetBit(0), 0);
Assert.AreEqual(test.GetBit(1), 1);
}
[TestMethod]
public void TestGetBits()
{
const byte test = 0x1F;
var output = test.GetBits();
CollectionAssert.AreEqual(output as byte[] ?? output.ToArray(), new byte[] {1, 1, 1, 1, 1, 0, 0, 0});
}
[TestMethod]
public void TestGetByte()
{
Assert.AreEqual(new byte[] {1, 1, 1, 1, 1, 0, 0, 0}.GetByte(), 0x1F);
Assert.AreEqual(new byte[] {0, 1}.GetByte(), 2);
}
[TestMethod]
public void TestGetNibbles()
{
const byte nibbleTest = 0xA5;
var (lowerNibble, upperNibble) = nibbleTest.GetNibbles();
Assert.AreEqual(lowerNibble, 0x5);
Assert.AreEqual(upperNibble, 0xA);
}
}
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MSTest.TestAdapter" version="1.2.1" targetFramework="net47" />
<package id="MSTest.TestFramework" version="1.2.1" targetFramework="net47" />
</packages>