Skip to content

Commit 125f2d5

Browse files
authored
Add tests (#4)
* Add tests * Update PR instruction
1 parent 4620199 commit 125f2d5

File tree

13 files changed

+637
-1
lines changed

13 files changed

+637
-1
lines changed

.github/workflows/pr-validation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
run: dotnet build --configuration Release -warnaserror
2828

2929
- name: Run unit tests
30-
run: dotnet test --no-build --verbosity normal
30+
run: dotnet test --configuration Release --verbosity normal
3131

3232
- name: Validate mapping JSON files
3333
run: |

drum-midi-remapper.sln

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Managers", "src\Managers\Ma
1313
EndProject
1414
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CLI", "src\CLI\CLI.csproj", "{36E27E57-4986-4178-98F8-3B4F6D985E2C}"
1515
EndProject
16+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0AB3BF05-4346-4AA6-1389-037BE0695223}"
17+
EndProject
18+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Managers.Tests", "tests\Managers.Tests\Managers.Tests.csproj", "{04A8B018-1954-48B8-BAAF-E17385114845}"
19+
EndProject
20+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Models.Tests", "tests\Models.Tests\Models.Tests.csproj", "{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}"
21+
EndProject
22+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services.Tests", "tests\Services.Tests\Services.Tests.csproj", "{3CECB972-EFFD-422B-9109-4D0D5AB6441E}"
23+
EndProject
1624
Global
1725
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1826
Debug|Any CPU = Debug|Any CPU
@@ -71,6 +79,42 @@ Global
7179
{36E27E57-4986-4178-98F8-3B4F6D985E2C}.Release|x64.Build.0 = Release|Any CPU
7280
{36E27E57-4986-4178-98F8-3B4F6D985E2C}.Release|x86.ActiveCfg = Release|Any CPU
7381
{36E27E57-4986-4178-98F8-3B4F6D985E2C}.Release|x86.Build.0 = Release|Any CPU
82+
{04A8B018-1954-48B8-BAAF-E17385114845}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
83+
{04A8B018-1954-48B8-BAAF-E17385114845}.Debug|Any CPU.Build.0 = Debug|Any CPU
84+
{04A8B018-1954-48B8-BAAF-E17385114845}.Debug|x64.ActiveCfg = Debug|Any CPU
85+
{04A8B018-1954-48B8-BAAF-E17385114845}.Debug|x64.Build.0 = Debug|Any CPU
86+
{04A8B018-1954-48B8-BAAF-E17385114845}.Debug|x86.ActiveCfg = Debug|Any CPU
87+
{04A8B018-1954-48B8-BAAF-E17385114845}.Debug|x86.Build.0 = Debug|Any CPU
88+
{04A8B018-1954-48B8-BAAF-E17385114845}.Release|Any CPU.ActiveCfg = Release|Any CPU
89+
{04A8B018-1954-48B8-BAAF-E17385114845}.Release|Any CPU.Build.0 = Release|Any CPU
90+
{04A8B018-1954-48B8-BAAF-E17385114845}.Release|x64.ActiveCfg = Release|Any CPU
91+
{04A8B018-1954-48B8-BAAF-E17385114845}.Release|x64.Build.0 = Release|Any CPU
92+
{04A8B018-1954-48B8-BAAF-E17385114845}.Release|x86.ActiveCfg = Release|Any CPU
93+
{04A8B018-1954-48B8-BAAF-E17385114845}.Release|x86.Build.0 = Release|Any CPU
94+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
95+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
96+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Debug|x64.ActiveCfg = Debug|Any CPU
97+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Debug|x64.Build.0 = Debug|Any CPU
98+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Debug|x86.ActiveCfg = Debug|Any CPU
99+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Debug|x86.Build.0 = Debug|Any CPU
100+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
101+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Release|Any CPU.Build.0 = Release|Any CPU
102+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Release|x64.ActiveCfg = Release|Any CPU
103+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Release|x64.Build.0 = Release|Any CPU
104+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Release|x86.ActiveCfg = Release|Any CPU
105+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4}.Release|x86.Build.0 = Release|Any CPU
106+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
107+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Debug|Any CPU.Build.0 = Debug|Any CPU
108+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Debug|x64.ActiveCfg = Debug|Any CPU
109+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Debug|x64.Build.0 = Debug|Any CPU
110+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Debug|x86.ActiveCfg = Debug|Any CPU
111+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Debug|x86.Build.0 = Debug|Any CPU
112+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Release|Any CPU.ActiveCfg = Release|Any CPU
113+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Release|Any CPU.Build.0 = Release|Any CPU
114+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Release|x64.ActiveCfg = Release|Any CPU
115+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Release|x64.Build.0 = Release|Any CPU
116+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Release|x86.ActiveCfg = Release|Any CPU
117+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E}.Release|x86.Build.0 = Release|Any CPU
74118
EndGlobalSection
75119
GlobalSection(SolutionProperties) = preSolution
76120
HideSolutionNode = FALSE
@@ -80,5 +124,8 @@ Global
80124
{E5A71B17-7DDC-452E-AE20-141AFDAE906A} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
81125
{92335A36-F5AE-45AA-B691-5054C217E33A} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
82126
{36E27E57-4986-4178-98F8-3B4F6D985E2C} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
127+
{04A8B018-1954-48B8-BAAF-E17385114845} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
128+
{C3C581BD-E5DE-4CC4-B9A5-9F76602C69A4} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
129+
{3CECB972-EFFD-422B-9109-4D0D5AB6441E} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
83130
EndGlobalSection
84131
EndGlobal
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using Models;
2+
3+
namespace Managers.Tests.Implementations
4+
{
5+
public class CliArgumentManagerTest
6+
{
7+
[Fact]
8+
public async Task Execute_ValidArguments_ReturnsRemapVariables()
9+
{
10+
var manager = new CliArgumentManager();
11+
var args = new[] { "GuitarPro", "LogicPro", "test.mid" };
12+
13+
var result = await manager.Execute(args);
14+
15+
Assert.Equal(DrumMapType.GuitarPro, result.SourceMapType);
16+
Assert.Equal(DrumMapType.LogicPro, result.TargetMapType);
17+
Assert.Equal("test.mid", result.MidiPath);
18+
}
19+
20+
[Fact]
21+
public async Task Execute_InsufficientArguments_ThrowsNullReferenceException()
22+
{
23+
var manager = new CliArgumentManager();
24+
var args = new[] { "GuitarPro", "LogicPro" };
25+
26+
var ex = await Assert.ThrowsAsync<NullReferenceException>(() => manager.Execute(args));
27+
Assert.Contains("Insufficient arguments", ex.Message);
28+
}
29+
30+
[Fact]
31+
public async Task Execute_InvalidSourceMap_ThrowsArgumentException()
32+
{
33+
var manager = new CliArgumentManager();
34+
var args = new[] { "InvalidMap", "LogicPro", "test.mid" };
35+
36+
var ex = await Assert.ThrowsAsync<ArgumentException>(() => manager.Execute(args));
37+
Assert.Contains("Invalid source map", ex.Message);
38+
}
39+
40+
[Fact]
41+
public async Task Execute_InvalidTargetMap_ThrowsArgumentException()
42+
{
43+
var manager = new CliArgumentManager();
44+
var args = new[] { "GuitarPro", "InvalidMap", "test.mid" };
45+
46+
var ex = await Assert.ThrowsAsync<ArgumentException>(() => manager.Execute(args));
47+
Assert.Contains("Invalid target map", ex.Message);
48+
}
49+
}
50+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Moq;
2+
using Services.Contracts;
3+
using Models;
4+
5+
namespace Managers.Tests.Implementations;
6+
7+
public class MidiMapManagerTest
8+
{
9+
private const DrumMapType SOURCE = DrumMapType.GuitarPro;
10+
private const DrumMapType TARGET = DrumMapType.StevenSlate;
11+
private const string FILENAME = "test.mid";
12+
13+
[Fact]
14+
public async Task RemapMidi_CallsServicesWithCorrectParameters()
15+
{
16+
// Arrange
17+
var mockMapLoader = new Mock<IMapLoaderService>();
18+
var mockMidiFileService = new Mock<IMidiFileService>();
19+
20+
var sourceMap = new DrumMap();
21+
var targetMap = new DrumMap();
22+
23+
var variables = new RemapVariables
24+
{
25+
SourceMapType = SOURCE,
26+
TargetMapType = TARGET,
27+
MidiPath = FILENAME
28+
};
29+
30+
mockMapLoader.Setup(m => m.LoadAsync(SOURCE)).ReturnsAsync(sourceMap);
31+
mockMapLoader.Setup(m => m.LoadAsync(TARGET)).ReturnsAsync(targetMap);
32+
33+
var manager = new MidiMapManager(mockMapLoader.Object, mockMidiFileService.Object);
34+
35+
// Act
36+
await manager.RemapMidi(variables);
37+
38+
// Assert
39+
mockMapLoader.Verify(m => m.LoadAsync(SOURCE), Times.Once);
40+
mockMapLoader.Verify(m => m.LoadAsync(TARGET), Times.Once);
41+
mockMidiFileService.Verify(m => m.RemapAsync(sourceMap, targetMap, "test.mid"), Times.Once);
42+
}
43+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<IsPackable>false</IsPackable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="coverlet.collector" Version="6.0.2" />
12+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
13+
<PackageReference Include="Moq" Version="4.20.72" />
14+
<PackageReference Include="xunit" Version="2.9.2" />
15+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<Using Include="Xunit" />
20+
<Using Include="Managers.Implementations" />
21+
</ItemGroup>
22+
23+
<ItemGroup>
24+
<ProjectReference Include="..\..\src\Managers\Managers.csproj" />
25+
</ItemGroup>
26+
27+
</Project>

tests/Models.Tests/DrumMapTest.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
namespace Models.Tests;
2+
3+
public class DrumMapTest
4+
{
5+
[Fact]
6+
public void DrumMap_DefaultConstructor_InitializesProperties()
7+
{
8+
var drumMap = new DrumMap();
9+
10+
Assert.NotNull(drumMap.Name);
11+
Assert.Equal(string.Empty, drumMap.Name);
12+
Assert.NotNull(drumMap.Mapping);
13+
Assert.Empty(drumMap.Mapping);
14+
}
15+
16+
[Fact]
17+
public void DrumMap_CanSetName()
18+
{
19+
var drumMap = new DrumMap
20+
{
21+
Name = "My Drum Map"
22+
};
23+
24+
Assert.Equal("My Drum Map", drumMap.Name);
25+
}
26+
27+
[Fact]
28+
public void DrumMap_CanAddMapping()
29+
{
30+
var drumMap = new DrumMap();
31+
drumMap.Mapping["Kick"] = 36;
32+
drumMap.Mapping["Snare"] = 38;
33+
34+
Assert.Equal(2, drumMap.Mapping.Count);
35+
Assert.Equal(36, drumMap.Mapping["Kick"]);
36+
Assert.Equal(38, drumMap.Mapping["Snare"]);
37+
}
38+
39+
[Fact]
40+
public void DrumMap_CanUpdateMapping()
41+
{
42+
var drumMap = new DrumMap();
43+
drumMap.Mapping["Kick"] = 36;
44+
drumMap.Mapping["Kick"] = 35;
45+
46+
Assert.Single(drumMap.Mapping);
47+
Assert.Equal(35, drumMap.Mapping["Kick"]);
48+
}
49+
50+
[Fact]
51+
public void DrumMap_CanRemoveMapping()
52+
{
53+
var drumMap = new DrumMap();
54+
drumMap.Mapping["Kick"] = 36;
55+
drumMap.Mapping.Remove("Kick");
56+
57+
Assert.Empty(drumMap.Mapping);
58+
}
59+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
namespace Models.Tests;
2+
3+
public class DrumMapTypeTest
4+
{
5+
[Fact]
6+
public void DrumMapType_ContainsExpectedValues()
7+
{
8+
Assert.Equal(0, (int)DrumMapType.StevenSlate);
9+
Assert.Equal(1, (int)DrumMapType.GuitarPro);
10+
Assert.Equal(2, (int)DrumMapType.LogicPro);
11+
Assert.Equal(3, (int)DrumMapType.ProTools);
12+
}
13+
14+
[Theory]
15+
[InlineData(DrumMapType.StevenSlate)]
16+
[InlineData(DrumMapType.GuitarPro)]
17+
[InlineData(DrumMapType.LogicPro)]
18+
[InlineData(DrumMapType.ProTools)]
19+
public void DrumMapType_IsDefined(DrumMapType type)
20+
{
21+
Assert.True(Enum.IsDefined(type));
22+
}
23+
24+
[Theory]
25+
[InlineData("StevenSlate", DrumMapType.StevenSlate)]
26+
[InlineData("GuitarPro", DrumMapType.GuitarPro)]
27+
[InlineData("LogicPro", DrumMapType.LogicPro)]
28+
[InlineData("ProTools", DrumMapType.ProTools)]
29+
public void DrumMapType_ParseString_ReturnsCorrectEnum(string name, DrumMapType expected)
30+
{
31+
var parsed = (DrumMapType)Enum.Parse(typeof(DrumMapType), name);
32+
Assert.Equal(expected, parsed);
33+
}
34+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<IsPackable>false</IsPackable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="coverlet.collector" Version="6.0.2" />
12+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
13+
<PackageReference Include="xunit" Version="2.9.2" />
14+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\..\src\Models\Models.csproj" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<Using Include="Xunit" />
23+
<Using Include="Models" />
24+
</ItemGroup>
25+
</Project>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
namespace Models.Tests;
2+
3+
public class RemapVariablesTest
4+
{
5+
[Fact]
6+
public void RemapVariables_DefaultConstructor_InitializesProperties()
7+
{
8+
var remapVariables = new RemapVariables
9+
{
10+
SourceMapType = DrumMapType.GuitarPro,
11+
TargetMapType = DrumMapType.LogicPro,
12+
MidiPath = "test.mid"
13+
};
14+
15+
Assert.Equal(DrumMapType.GuitarPro, remapVariables.SourceMapType);
16+
Assert.Equal(DrumMapType.LogicPro, remapVariables.TargetMapType);
17+
Assert.Equal("test.mid", remapVariables.MidiPath);
18+
}
19+
20+
[Fact]
21+
public void RemapVariables_CanSetSourceMapType()
22+
{
23+
var remapVariables = new RemapVariables
24+
{
25+
SourceMapType = DrumMapType.LogicPro,
26+
TargetMapType = DrumMapType.GuitarPro,
27+
MidiPath = "file.mid"
28+
};
29+
30+
remapVariables.SourceMapType = DrumMapType.GuitarPro;
31+
32+
Assert.Equal(DrumMapType.GuitarPro, remapVariables.SourceMapType);
33+
}
34+
35+
[Fact]
36+
public void RemapVariables_CanSetTargetMapType()
37+
{
38+
var remapVariables = new RemapVariables
39+
{
40+
SourceMapType = DrumMapType.GuitarPro,
41+
TargetMapType = DrumMapType.LogicPro,
42+
MidiPath = "file.mid"
43+
};
44+
45+
remapVariables.TargetMapType = DrumMapType.GuitarPro;
46+
47+
Assert.Equal(DrumMapType.GuitarPro, remapVariables.TargetMapType);
48+
}
49+
50+
[Fact]
51+
public void RemapVariables_CanSetMidiPath()
52+
{
53+
var remapVariables = new RemapVariables
54+
{
55+
SourceMapType = DrumMapType.GuitarPro,
56+
TargetMapType = DrumMapType.LogicPro,
57+
MidiPath = "old.mid"
58+
};
59+
60+
remapVariables.MidiPath = "new.mid";
61+
62+
Assert.Equal("new.mid", remapVariables.MidiPath);
63+
}
64+
}

0 commit comments

Comments
 (0)