Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements to TouramentManager.ExtensionMethods #95

Merged
merged 2 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="nunit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0">
<PrivateAssets>all</PrivateAssets>
Expand Down
1 change: 1 addition & 0 deletions Axuno.Tools.Tests/Axuno.Tools.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="nunit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0">
<PrivateAssets>all</PrivateAssets>
Expand Down
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<Copyright>Copyright 2011-$(CurrentYear) axuno gGmbH</Copyright>
<RepositoryUrl>https://github.com/axuno/Volleyball-League</RepositoryUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<Version>6.4.1</Version>
<FileVersion>6.4.1</FileVersion>
<Version>6.4.2</Version>
<FileVersion>6.4.2</FileVersion>
<AssemblyVersion>6.0.0.0</AssemblyVersion> <!--only update AssemblyVersion with major releases -->
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
Expand Down
2 changes: 2 additions & 0 deletions League.Demo/League.Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<Product>League.Demo</Product>
<TargetFramework>net6.0</TargetFramework>
<NeutralLanguage>en</NeutralLanguage>
<!-- With dotnet, add parameter: -p:SatelliteResourceLanguages="""en;de""" -->
<SatelliteResourceLanguages>en;de</SatelliteResourceLanguages>
</PropertyGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions League.Tests/League.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.14" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.1" />
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0">
Expand Down
20 changes: 6 additions & 14 deletions League/Models/MatchViewModels/EnterResultViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using TournamentManager.DAL;
using TournamentManager.DAL.EntityClasses;
using TournamentManager.ExtensionMethods;
using TournamentManager.Match;
using TournamentManager.ModelValidators;

namespace League.Models.MatchViewModels;
Expand Down Expand Up @@ -71,12 +70,12 @@ public void MapEntityToFormFields()
Match.Sets.Sort((int)SetFieldIndex.SequenceNo, ListSortDirection.Ascending);
foreach (var set in Match.Sets)
{
Sets.Add(new PointResultNullable(set.HomeBallPoints, set.GuestBallPoints));
Sets.Add(new PointResult(set.HomeBallPoints, set.GuestBallPoints));
}

while (Sets.Count < _maxNumberOfSets)
{
Sets.Add(new PointResultNullable(null, null));
Sets.Add(new PointResult(default, default(int?)));
}

Id = Match.Id;
Expand All @@ -99,18 +98,11 @@ public void MapFormFieldsToEntity()

// Add sets to entity
Match.Sets.Clear(true);
for (var i = 0; i < Sets.Count; i++)
{
// sets where home and guest ball points are NULL, will be ignored
if (Sets[i].Home.HasValue || Sets[i].Guest.HasValue)
{
// home or guest NULL values are invalidated with -1
Match.Sets.Add(new SetEntity { MatchId = Match.Id, SequenceNo = i + 1, HomeBallPoints = Sets[i].Home ?? -1, GuestBallPoints = Sets[i].Guest ?? -1 });
}
}
// sets where home or guest ball points are NULL will be ignored
Match.Sets.Add(Match.Id, Sets);

// point calculation must run before validation because of tie-break handling
Match.Sets.CalculateSetPoints(Round!.SetRule, Round.MatchRule);
_ = Match.Sets.CalculateSetPoints(Round!.SetRule, Round.MatchRule);
Match.Remarks = Remarks;
Match.ChangeSerial++;
Match.IsComplete = true;
Expand Down Expand Up @@ -147,7 +139,7 @@ public void MapFormFieldsToEntity()
[MaxLength(2000)]
public string? Remarks { get; set; }

public List<PointResultNullable> Sets { get; set; } = new();
public List<PointResult> Sets { get; set; } = new();

#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ public void SetVenueId(long? venueId)
{
if (venueId == VenueId) return;

if (!OrigVenueId.HasValue)
OrigVenueId = VenueId;
OrigVenueId ??= VenueId;

VenueId = venueId;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,6 @@ namespace TournamentManager.DAL.EntityClasses
{
public partial class SetEntity
{
/// <summary>
/// Assigns &quot;set points&quot; to the <see cref="SetEntity"/>.
/// The <see cref="SetEntity.IsOverruled"/> property will be set to <see langword="false"/>
/// </summary>
/// <param name="setRule">The <see cref="SetRuleEntity"/> with the rules to apply.</param>
public void CalculateSetPoints(SetRuleEntity setRule)
{
IsOverruled = false;
if (HomeBallPoints > GuestBallPoints)
{
HomeSetPoints = setRule.PointsSetWon;
GuestSetPoints = setRule.PointsSetLost;
}
else if (HomeBallPoints < GuestBallPoints)
{
HomeSetPoints = setRule.PointsSetLost;
GuestSetPoints = setRule.PointsSetWon;
}
else
{
HomeSetPoints = GuestSetPoints = setRule.PointsSetTie;
}
}

/// <summary>
/// Sets home/guest ball points and home/guest set points.
/// The <see cref="SetEntity.IsOverruled"/> property will be set to <see langword="true"/>,
/// while <see cref="SetEntity.IsTieBreak"/> will be set to <see langword="false"/>.
/// </summary>
/// <param name="homeBallPoints"></param>
/// <param name="guestBallPoints"></param>
/// <param name="homeSetPoints"></param>
/// <param name="guestSetPoints"></param>
public void Overrule(int homeBallPoints, int guestBallPoints, int homeSetPoints, int guestSetPoints)
{
HomeBallPoints = homeBallPoints;
GuestBallPoints = guestBallPoints;
HomeSetPoints = homeSetPoints;
GuestSetPoints = guestSetPoints;
IsTieBreak = false;
IsOverruled = true;
}

protected override void OnBeforeEntitySave()
{
var now = DateTime.UtcNow;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using FluentAssertions;
using TournamentManager.DAL.EntityClasses;
using TournamentManager.ExtensionMethods;
using TournamentManager.ModelValidators;
using TournamentManager.MultiTenancy;

namespace TournamentManager.Tests.ExtensionMethods;

[TestFixture]
public class MatchEntityExtensionTests
{
[Test]
public void Calc_With_No_Sets_Should_Not_Throw()
{
var matchRule = GetMatchRule_NoTieBreakRule();
var setRule = GetSetRule();
var match = new MatchEntity(1234);

Assert.That(del: () => _ = match.Sets.CalculateSetPoints(setRule, matchRule), Throws.Nothing);
}

[TestCase("25:1 25:2 25:3", 3, 0)]
[TestCase("25:1 25:2 1:25 1:25 15:1", 3, 0)]
[TestCase("1:25 2:25 2:25", 0, 3)]
[TestCase("1:25 2:25 25:13 25:1 1:15", 0, 3)]
[TestCase("1:25 25:1", 1, 1)]
public void Calc_MatchPoints_No_TieBreakRule(string setResults, int expectedHome, int expectedGuest)
{
// Note: Test cases are not validated against the rules here, but they are valid.
// Validation is tested in ModelValidator tests

var matchRule = GetMatchRule_NoTieBreakRule();
var setRule = GetSetRule();
var match = new MatchEntity(1234);
match.Sets.Add(match.Id, setResults);
_ = match.Sets.CalculateSetPoints(setRule, matchRule);
_ = match.CalculateMatchPoints(matchRule);

var pointResult = new PointResult(match.HomePoints, match.GuestPoints);
var expectedResult = new PointResult(expectedHome, expectedGuest);

pointResult.Should().BeEquivalentTo(expectedResult);
}

[TestCase("25:1 25:2 25:3", 3, 0)]
[TestCase("25:1 25:2 1:25 1:25 15:1", 2, 1)]
[TestCase("1:25 2:25 2:25", 0, 3)]
[TestCase("1:25 2:25 25:13 25:1 1:15", 1, 2)]
[TestCase("1:25 25:1", 1, 1)]
public void Calc_MatchPoints_With_TieBreakRule(string setResults, int expectedHome, int expectedGuest)
{
// Note: Test cases are not validated against the rules here, but they are valid.
// Validation is tested in ModelValidator tests

var matchRule = GetMatchRule_TieBreakRule();
var setRule = GetSetRule();
var match = new MatchEntity(1234);
match.Sets.Add(match.Id, setResults);
_ = match.Sets.CalculateSetPoints(setRule, matchRule);
_ = match.CalculateMatchPoints(matchRule);

var pointResult = new PointResult(match.HomePoints, match.GuestPoints);
var expectedResult = new PointResult(expectedHome, expectedGuest);

pointResult.Should().BeEquivalentTo(expectedResult);
}

[Test]
public void Calc_MatchPoints_With_TieBreakRule_Throws()
{
var matchRule = GetMatchRule_TieBreakRule();
var setRule = GetSetRule();
var match = new MatchEntity(1234);
match.Sets.Add(match.Id, "25:1 25:2 1:25 1:25 15:1");
_ = match.Sets.CalculateSetPoints(setRule, matchRule);

// This will trigger an exception, because the set points are tie
var lastSet = match.Sets.Last();
lastSet.HomeSetPoints = lastSet.GuestSetPoints = 0;

Assert.That(del: () => _ = match.CalculateMatchPoints(matchRule), Throws.InvalidOperationException);
}

private static MatchRuleEntity GetMatchRule_NoTieBreakRule()
{
return new MatchRuleEntity {
BestOf = true,
NumOfSets = 3,
PointsMatchWon = 3,
PointsMatchLost = 0,
PointsMatchTie = 1
};
}

private static MatchRuleEntity GetMatchRule_TieBreakRule()
{
return new MatchRuleEntity {
BestOf = true,
NumOfSets = 3,
PointsMatchWon = 3,
PointsMatchLost = 0,
PointsMatchWonAfterTieBreak = 2,
PointsMatchLostAfterTieBreak = 1,
PointsMatchTie = 1
};
}

private static SetRuleEntity GetSetRule()
{
return new SetRuleEntity {
NumOfPointsToWinRegular = 25,
NumOfPointsToWinTiebreak = 15,
PointsDiffToWinRegular = 2,
PointsDiffToWinTiebreak = 2,
PointsSetWon = 1,
PointsSetLost = 0,
PointsSetTie = 0
};
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using NUnit.Framework;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using TournamentManager.DAL.EntityClasses;

namespace TournamentManager.Tests.DAL_CustomExtensions;
namespace TournamentManager.Tests.ExtensionMethods;

[TestFixture]
public class MatchRuleEntityExtensionTests
Expand All @@ -11,7 +14,7 @@ public class MatchRuleEntityExtensionTests
[TestCase(true, 2, 3)]
public void Calculate_Max_Number_Of_Sets(bool isBestOf, int numOfSets, int expected)
{
var rule = new MatchRuleEntity {BestOf = isBestOf, NumOfSets = numOfSets};
var rule = new MatchRuleEntity { BestOf = isBestOf, NumOfSets = numOfSets };
Assert.AreEqual(expected, rule.MaxNumOfSets());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
using TournamentManager.DAL.EntityClasses;
using TournamentManager.ExtensionMethods;

namespace TournamentManager.Tests.DAL_CustomExtensions;
namespace TournamentManager.Tests.ExtensionMethods;

[TestFixture]
public class SetEntityExtensionTests
{
[TestCase(25, 1, 3,1)]
[TestCase(25, 1, 3, 1)]
[TestCase(1, 25, 1, 3)]
[TestCase(25, 25, 2, 2)]
public void Calculate_Set_Points(int homeBallPts, int guestBallPts, int expectedHomeSetPts, int expectedGuestSetPts)
{
var set = new SetEntity {HomeBallPoints = homeBallPts, GuestBallPoints = guestBallPts};
var setRule = new SetRuleEntity { PointsSetWon = 3, PointsSetLost = 1, PointsSetTie = 2};
var set = new SetEntity { HomeBallPoints = homeBallPts, GuestBallPoints = guestBallPts };
var setRule = new SetRuleEntity { PointsSetWon = 3, PointsSetLost = 1, PointsSetTie = 2 };
set.CalculateSetPoints(setRule);
Assert.Multiple(() =>
{
Expand All @@ -30,7 +30,7 @@ public void Calculate_Set_Points(int homeBallPts, int guestBallPts, int expected
[TestCase(1, 25, 1, 2)]
public void Overrule_Set_Points(int homeBallPts, int guestBallPts, int homeSetPts, int guestSetPts)
{
var set = new SetEntity { HomeBallPoints = homeBallPts, GuestBallPoints = guestBallPts, IsTieBreak = true, IsOverruled = false};
var set = new SetEntity { HomeBallPoints = homeBallPts, GuestBallPoints = guestBallPts, IsTieBreak = true, IsOverruled = false };
set.Overrule(homeBallPts, guestBallPts, homeSetPts, guestSetPts);
Assert.Multiple(() =>
{
Expand All @@ -40,4 +40,4 @@ public void Overrule_Set_Points(int homeBallPts, int guestBallPts, int homeSetPt
Assert.IsTrue(set.IsOverruled);
});
}
}
}
Loading