diff --git a/Tests/TryAtSoftware.CleanTests.UnitTests/ConstructionManagerTests.cs b/Tests/TryAtSoftware.CleanTests.UnitTests/ConstructionManagerTests.cs
index e73fa87..ca5c91a 100644
--- a/Tests/TryAtSoftware.CleanTests.UnitTests/ConstructionManagerTests.cs
+++ b/Tests/TryAtSoftware.CleanTests.UnitTests/ConstructionManagerTests.cs
@@ -2,6 +2,8 @@
using System.Text.Json;
using TryAtSoftware.CleanTests.Core.Construction;
+using TryAtSoftware.CleanTests.Core.Interfaces;
+using TryAtSoftware.CleanTests.Core.XUnit;
using TryAtSoftware.CleanTests.UnitTests.Constants;
using TryAtSoftware.CleanTests.UnitTests.Extensions;
using TryAtSoftware.CleanTests.UnitTests.Parametrization;
@@ -9,8 +11,7 @@
public class ConstructionManagerTests
{
- [Theory(Timeout = UnitTestConstants.Timeout)]
- [MemberData(nameof(GetDependenciesManagerSetups))]
+ [Theory(Timeout = UnitTestConstants.Timeout), MemberData(nameof(GetDependenciesManagerSetups))]
public Task DependencyGraphsShouldBeConstructedSuccessfully(EnvironmentSetup setup, string pathToExpectedResult)
{
var assemblyTestData = setup.MaterializeAsAssemblyData();
@@ -33,167 +34,208 @@ public Task DependencyGraphsShouldBeConstructedSuccessfully(EnvironmentSetup set
[Fact]
public void OuterDemandsShouldBeAppliedCorrectlyAtRootLevel()
{
- var utilitiesCount = RandomizationHelper.RandomInteger(3, 10);
var setup = new EnvironmentSetup("outer_demands_env");
- setup.WithCategory("FL1", 1).WithCategory("FL2", utilitiesCount).WithCategory("SL1", utilitiesCount);
- setup.WithRequirements("FL1", 1, "SL1");
-
- for (var i = 1; i <= utilitiesCount; i++)
+ var count = RandomizationHelper.RandomInteger(3, 10);
+ PrepareForOuterDemandsTesting(setup, depth: 1, count);
+
+ for (var i = 1; i <= count; i++)
{
- var characteristic = $"C-{i}";
- setup.WithCharacteristics("FL2", i, characteristic);
- setup.WithOuterDemands("SL1", i, "FL2", characteristic);
+ setup.WithCharacteristics("Q", i, $"O{i}");
+ setup.WithOuterDemands("N1", i, "Q", $"O{i}");
}
var assemblyTestData = setup.MaterializeAsAssemblyData();
var manager = new ConstructionManager(assemblyTestData);
- var fl1Utilities = assemblyTestData.CleanUtilities.Get("FL1").ToArray();
- Assert.Single(fl1Utilities);
-
- var fl2Utilities = assemblyTestData.CleanUtilities.Get("FL2").ToArray();
- Assert.Equal(utilitiesCount, fl2Utilities.Length);
-
- var sl1Utilities = assemblyTestData.CleanUtilities.Get("SL1").ToArray();
- Assert.Equal(utilitiesCount, sl1Utilities.Length);
+ var matrix = ExtractMatrixForOuterDemandsTesting(assemblyTestData, depth: 1, count);
- for (var i = 0; i < utilitiesCount; i++)
+ for (var i = 0; i < count; i++)
{
- var utilityIds = new[] { fl1Utilities[0].Id, fl2Utilities[i].Id };
+ var utilityIds = new[] { matrix[0][0].Id, matrix[^1][i].Id };
var constructionGraphs = manager.BuildIndividualConstructionGraphs(utilityIds);
-
Assert.Single(constructionGraphs);
- var fl1ConstructionGraph = constructionGraphs[0][0];
-
- Assert.NotNull(fl1Utilities);
- Assert.Equal(fl1Utilities[0].Id, fl1ConstructionGraph.Id);
-
- var sl1ConstructionGraph = Assert.Single(fl1ConstructionGraph.Dependencies);
- Assert.NotNull(sl1ConstructionGraph);
- Assert.Equal(sl1Utilities[i].Id, sl1ConstructionGraph.Id);
-
- var fl2ConstructionGraph = constructionGraphs[0][1];
- Assert.NotNull(fl2ConstructionGraph);
- Assert.Equal(fl2Utilities[i].Id, fl2ConstructionGraph.Id);
-
- Assert.Empty(fl2ConstructionGraph.Dependencies);
+ Assert.Equal(2, constructionGraphs[0].Length);
+
+ var penultConstructionGraph = constructionGraphs[0][0];
+ Assert.Equal(matrix[0][0].Id, penultConstructionGraph.Id);
+ Assert.Single(penultConstructionGraph.Dependencies);
+
+ var qConstructionGraph = constructionGraphs[0][1];
+ Assert.Equal(matrix[^1][i].Id, qConstructionGraph.Id);
+ Assert.Empty(qConstructionGraph.Dependencies);
+
+ var lastConstructionGraph = penultConstructionGraph.Dependencies[0];
+ Assert.Equal(matrix[1][i].Id, lastConstructionGraph.Id);
+ Assert.Empty(lastConstructionGraph.Dependencies);
}
}
[Fact]
public void UnsatisfiableOuterDemandsShouldBeHandledCorrectlyAtRootLevel()
{
- var utilitiesCount = RandomizationHelper.RandomInteger(3, 10);
var setup = new EnvironmentSetup("outer_demands_env");
- setup.WithCategory("FL1", 1).WithCategory("FL2", utilitiesCount).WithCategory("SL1", utilitiesCount);
- setup.WithRequirements("FL1", 1, "SL1");
+ var count = RandomizationHelper.RandomInteger(3, 10);
+ PrepareForOuterDemandsTesting(setup, depth: 1, count);
- for (var i = 1; i <= utilitiesCount; i++)
+ for (var i = 1; i <= count; i++)
{
- setup.WithCharacteristics("FL2", i, $"C{i}");
- setup.WithOuterDemands("SL1", i, "FL2", $"D{i}");
+ setup.WithCharacteristics("Q", i, $"O{i}");
+ setup.WithOuterDemands("N1", i, "Q", $"X{i}");
}
var assemblyTestData = setup.MaterializeAsAssemblyData();
var manager = new ConstructionManager(assemblyTestData);
- var fl1Utilities = assemblyTestData.CleanUtilities.Get("FL1").ToArray();
- Assert.Single(fl1Utilities);
+ var matrix = ExtractMatrixForOuterDemandsTesting(assemblyTestData, depth: 1, count);
- var fl2Utilities = assemblyTestData.CleanUtilities.Get("FL2").ToArray();
- Assert.Equal(utilitiesCount, fl2Utilities.Length);
-
- for (var i = 0; i < utilitiesCount; i++)
+ for (var i = 0; i < count; i++)
{
- var utilityIds = new[] { fl1Utilities[0].Id, fl2Utilities[i].Id };
+ var utilityIds = new[] { matrix[0][0].Id, matrix[^1][i].Id };
var constructionGraphs = manager.BuildIndividualConstructionGraphs(utilityIds);
-
Assert.Empty(constructionGraphs);
}
}
- [Fact]
- public void OuterDemandsShouldBeAppliedCorrectlyAtDeeperLevels()
+ [Theory, MemberData(nameof(GetDepthMembers))]
+ public void OuterDemandsShouldBeAppliedCorrectlyAtDeeperLevels(int depth)
{
- var utilitiesCount = RandomizationHelper.RandomInteger(3, 10);
var setup = new EnvironmentSetup("outer_demands_env");
- setup.WithCategory("FL1", 1).WithCategory("SL1", 1).WithCategory("SL2", utilitiesCount).WithCategory("TL1", utilitiesCount);
- setup.WithRequirements("FL1", 1, "SL1", "SL2").WithRequirements("SL1", 1, "TL1");
+ var count = RandomizationHelper.RandomInteger(3, 10);
+ PrepareForOuterDemandsTesting(setup, depth, count);
- for (var i = 1; i <= utilitiesCount; i++)
+ for (var i = 1; i <= count; i++)
{
- var characteristic = $"C-{i}";
- setup.WithCharacteristics("SL2", i, characteristic);
- setup.WithOuterDemands("TL1", i, "SL2", characteristic);
+ setup.WithCharacteristics("Q", i, $"O{i}");
+ setup.WithOuterDemands($"N{depth}", i, "Q", $"O{i}");
}
var assemblyTestData = setup.MaterializeAsAssemblyData();
var manager = new ConstructionManager(assemblyTestData);
- var fl1Utilities = assemblyTestData.CleanUtilities.Get("FL1").ToArray();
- Assert.Single(fl1Utilities);
-
- var sl1Utilities = assemblyTestData.CleanUtilities.Get("SL1").ToArray();
- Assert.Single(sl1Utilities);
-
- var sl2Utilities = assemblyTestData.CleanUtilities.Get("SL2").ToArray();
- Assert.Equal(utilitiesCount, sl2Utilities.Length);
-
- var tl1Utilities = assemblyTestData.CleanUtilities.Get("TL1").ToArray();
- Assert.Equal(utilitiesCount, tl1Utilities.Length);
+ var matrix = ExtractMatrixForOuterDemandsTesting(assemblyTestData, depth, count);
+ var constructionGraphs = manager.BuildIndividualConstructionGraphs(matrix[0].Select(x => x.Id));
+ AssertCorrectConstructionWithOuterDemandsAtDeeperLevels(constructionGraphs, matrix, depth, count);
+ }
- var utilityIds = new[] { fl1Utilities[0].Id };
- var constructionGraphs = manager.BuildIndividualConstructionGraphs(utilityIds);
+ [Theory, MemberData(nameof(GetDepthMembers))]
+ public void UnsatisfiableOuterDemandsShouldBeHandledCorrectlyAtDeeperLevels(int depth)
+ {
+ var setup = new EnvironmentSetup("outer_demands_env");
+ var count = RandomizationHelper.RandomInteger(3, 10);
+ PrepareForOuterDemandsTesting(setup, depth, count);
- Assert.Equal(utilitiesCount, constructionGraphs.Length);
- for (var i = 0; i < utilitiesCount; i++)
+ for (var i = 1; i <= count; i++)
{
- var fl1ConstructionGraph = constructionGraphs[i][0];
-
- Assert.NotNull(fl1Utilities);
- Assert.Equal(fl1Utilities[0].Id, fl1ConstructionGraph.Id);
- Assert.Equal(2, fl1ConstructionGraph.Dependencies.Count);
-
- var sl1ConstructionGraph = fl1ConstructionGraph.Dependencies[0];
- Assert.NotNull(sl1ConstructionGraph);
- Assert.Equal(sl1Utilities[0].Id, sl1ConstructionGraph.Id);
+ setup.WithCharacteristics("Q", i, $"O{i}");
+ setup.WithOuterDemands($"N{depth}", i, "Q", $"X{i}");
+ }
- var sl2ConstructionGraph = fl1ConstructionGraph.Dependencies[1];
- Assert.NotNull(sl2ConstructionGraph);
- Assert.Equal(sl2Utilities[i].Id, sl2ConstructionGraph.Id);
- Assert.Empty(sl2ConstructionGraph.Dependencies);
+ var assemblyTestData = setup.MaterializeAsAssemblyData();
+ var manager = new ConstructionManager(assemblyTestData);
- var tl1ConstructionGraph = Assert.Single(sl1ConstructionGraph.Dependencies);
- Assert.NotNull(tl1ConstructionGraph);
- Assert.Equal(tl1Utilities[i].Id, tl1ConstructionGraph.Id);
- Assert.Empty(tl1ConstructionGraph.Dependencies);
- }
+ var matrix = ExtractMatrixForOuterDemandsTesting(assemblyTestData, depth, count);
+ var constructionGraphs = manager.BuildIndividualConstructionGraphs(matrix[0].Select(x => x.Id));
+ Assert.Empty(constructionGraphs);
}
-
- [Fact]
- public void UnsatisfiableOuterDemandsShouldBeHandledCorrectlyAtDeeperLevels()
+
+ ///
+ /// N{depth} defines unsatisfiable outer demands towards N0, N1, ..., N{depth - 2}.
+ /// These unsatisfiable demands do not impact the construction of individual graphs,
+ /// as the referenced utilities are not located within the immediate higher hierarchical level.
+ ///
+ [Theory, MemberData(nameof(GetDepthMembers))]
+ public void OuterDemandsShouldOnlyTargetTheImmediateHigherLevel(int depth)
{
- var utilitiesCount = RandomizationHelper.RandomInteger(3, 10);
var setup = new EnvironmentSetup("outer_demands_env");
- setup.WithCategory("FL1", 1).WithCategory("SL1", 1).WithCategory("SL2", utilitiesCount).WithCategory("TL1", utilitiesCount);
- setup.WithRequirements("FL1", 1, "SL1", "SL2").WithRequirements("SL1", 1, "TL1");
+ var count = RandomizationHelper.RandomInteger(3, 10);
+ PrepareForOuterDemandsTesting(setup, depth, count);
- for (var i = 1; i <= utilitiesCount; i++)
+ for (var i = 1; i <= count; i++)
{
- setup.WithCharacteristics("SL2", i, $"C{i}");
- setup.WithOuterDemands("TL1", i, "SL2", $"D{i}");
+ setup.WithCharacteristics("Q", i, $"O{i}");
+ setup.WithOuterDemands($"N{depth}", i, "Q", $"O{i}");
+
+ for (var j = 0; j < depth - 1; j++)
+ {
+ setup.WithCharacteristics($"N{j}", 1, $"O{i}");
+ setup.WithOuterDemands($"N{depth}", i, $"N{j}", $"X{i}");
+ }
}
var assemblyTestData = setup.MaterializeAsAssemblyData();
var manager = new ConstructionManager(assemblyTestData);
- var fl1Utilities = assemblyTestData.CleanUtilities.Get("FL1").ToArray();
- Assert.Single(fl1Utilities);
+ var matrix = ExtractMatrixForOuterDemandsTesting(assemblyTestData, depth, count);
+ var constructionGraphs = manager.BuildIndividualConstructionGraphs(matrix[0].Select(x => x.Id));
+ AssertCorrectConstructionWithOuterDemandsAtDeeperLevels(constructionGraphs, matrix, depth, count);
+ }
- var utilityIds = new[] { fl1Utilities[0].Id };
- var constructionGraphs = manager.BuildIndividualConstructionGraphs(utilityIds);
+ ///
+ /// |N0| -> |N1| -> ... -> |N{depth - 2}| -> |N{depth - 1}| -> |N{depth}|
+ /// -> |Q| -----------------^
+ ///
+ /// N{depth} defines outer demands towards Q
+ ///
+ private static void PrepareForOuterDemandsTesting(EnvironmentSetup setup, int depth, int count)
+ {
+ for (var i = 0; i < depth; i++)
+ {
+ setup.WithCategory($"N{i}", 1);
+ setup.WithRequirements($"N{i}", 1, $"N{i + 1}");
+ }
- Assert.Empty(constructionGraphs);
+ setup.WithCategory($"N{depth}", count).WithCategory("Q", count);
+ if (depth > 1) setup.WithRequirements($"N{depth - 2}", 1, "Q");
+ }
+
+ ///
+ /// Returns a matrix of length `depth + 2`:
+ /// - The first `depth + 1` entries are reserved for the `N#` categories.
+ /// - The last entry is reserved for the `Q` category.
+ ///
+ private static ICleanUtilityDescriptor[][] ExtractMatrixForOuterDemandsTesting(CleanTestAssemblyData assemblyTestData, int depth, int count)
+ {
+ // NOTE: There are depth + 1 `N#` categories and `Q`.
+ var matrix = new ICleanUtilityDescriptor[depth + 2][];
+ for (var i = 0; i <= depth; i++) matrix[i] = assemblyTestData.CleanUtilities.Get($"N{i}").ToArray();
+ matrix[^1] = assemblyTestData.CleanUtilities.Get("Q").ToArray();
+
+ for (var i = 0; i < depth; i++) Assert.Single(matrix[i]);
+ for (var i = depth; i < matrix.Length; i++) Assert.Equal(count, matrix[i].Length);
+
+ return matrix;
+ }
+
+ private static void AssertCorrectConstructionWithOuterDemandsAtDeeperLevels(IndividualCleanUtilityConstructionGraph[][] constructionGraphs, ICleanUtilityDescriptor[][] matrix, int depth, int count)
+ {
+ Assert.Equal(count, constructionGraphs.Length);
+ for (var i = 0; i < count; i++)
+ {
+ var analyzedGraph = Assert.Single(constructionGraphs[i]);
+
+ for (var j = 0; j < depth - 2; j++)
+ {
+ Assert.Equal(matrix[j][0].Id, analyzedGraph.Id);
+ Assert.Single(analyzedGraph.Dependencies);
+
+ analyzedGraph = analyzedGraph.Dependencies[0];
+ }
+
+ Assert.Equal(matrix[depth - 2][0].Id, analyzedGraph.Id);
+ Assert.Equal(2, analyzedGraph.Dependencies.Count);
+
+ var penultConstructionGraph = analyzedGraph.Dependencies[0];
+ Assert.Equal(matrix[depth - 1][0].Id, penultConstructionGraph.Id);
+ Assert.Single(penultConstructionGraph.Dependencies);
+
+ var qConstructionGraph = analyzedGraph.Dependencies[1];
+ Assert.Equal(matrix[^1][i].Id, qConstructionGraph.Id);
+ Assert.Empty(qConstructionGraph.Dependencies);
+
+ var lastConstructionGraph = penultConstructionGraph.Dependencies[0];
+ Assert.Equal(matrix[depth][i].Id, lastConstructionGraph.Id);
+ Assert.Empty(lastConstructionGraph.Dependencies);
+ }
}
public static TheoryData GetDependenciesManagerSetups()
@@ -201,7 +243,15 @@ public static TheoryData GetDependenciesManagerSetups(
var data = new TheoryData();
foreach (var dependenciesManagerSetup in TestParameters.ConstructObservableConstructionManagerSetups())
data.Add(dependenciesManagerSetup.EnvironmentSetup, dependenciesManagerSetup.PathToExpectedResult);
-
+
+ return data;
+ }
+
+ public static TheoryData GetDepthMembers()
+ {
+ var data = new TheoryData();
+ for (var i = 2; i <= 10; i++) data.Add(i);
+
return data;
}
}
\ No newline at end of file
diff --git a/TryAtSoftware.CleanTests.Core/Attributes/ExternalDemandsAttribute.cs b/TryAtSoftware.CleanTests.Core/Attributes/ExternalDemandsAttribute.cs
index ec2705c..7618c95 100644
--- a/TryAtSoftware.CleanTests.Core/Attributes/ExternalDemandsAttribute.cs
+++ b/TryAtSoftware.CleanTests.Core/Attributes/ExternalDemandsAttribute.cs
@@ -3,10 +3,4 @@
using System;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
-public class ExternalDemandsAttribute : BaseDemandsAttribute
-{
- public ExternalDemandsAttribute(string category, params string[] demands)
- : base(category, demands)
- {
- }
-}
\ No newline at end of file
+public class ExternalDemandsAttribute(string category, params string[] demands) : BaseDemandsAttribute(category, demands);
\ No newline at end of file
diff --git a/TryAtSoftware.CleanTests.Core/Attributes/InternalDemandsAttribute.cs b/TryAtSoftware.CleanTests.Core/Attributes/InternalDemandsAttribute.cs
index df3b96a..004d345 100644
--- a/TryAtSoftware.CleanTests.Core/Attributes/InternalDemandsAttribute.cs
+++ b/TryAtSoftware.CleanTests.Core/Attributes/InternalDemandsAttribute.cs
@@ -3,10 +3,4 @@
using System;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
-public class InternalDemandsAttribute : BaseDemandsAttribute
-{
- public InternalDemandsAttribute(string category, params string[] demands)
- : base(category, demands)
- {
- }
-}
\ No newline at end of file
+public class InternalDemandsAttribute(string category, params string[] demands) : BaseDemandsAttribute(category, demands);
\ No newline at end of file
diff --git a/TryAtSoftware.CleanTests.Core/Attributes/OuterDemandsAttribute.cs b/TryAtSoftware.CleanTests.Core/Attributes/OuterDemandsAttribute.cs
index a87e416..85e128b 100644
--- a/TryAtSoftware.CleanTests.Core/Attributes/OuterDemandsAttribute.cs
+++ b/TryAtSoftware.CleanTests.Core/Attributes/OuterDemandsAttribute.cs
@@ -3,10 +3,4 @@
using System;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
-public class OuterDemandsAttribute : BaseDemandsAttribute
-{
- public OuterDemandsAttribute(string category, params string[] demands)
- : base(category, demands)
- {
- }
-}
\ No newline at end of file
+public class OuterDemandsAttribute(string category, params string[] demands) : BaseDemandsAttribute(category, demands);
\ No newline at end of file