diff --git a/DataAccess/DTOs/Converters/NdmCrossSections/CrackCalculatorFromDTOConvertStrategy.cs b/DataAccess/DTOs/Converters/NdmCrossSections/CrackCalculatorFromDTOConvertStrategy.cs index afb4249..5a1e104 100644 --- a/DataAccess/DTOs/Converters/NdmCrossSections/CrackCalculatorFromDTOConvertStrategy.cs +++ b/DataAccess/DTOs/Converters/NdmCrossSections/CrackCalculatorFromDTOConvertStrategy.cs @@ -1,25 +1,21 @@ using StructureHelperCommon.Infrastructures.Interfaces; -using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperCommon.Models; using StructureHelperLogics.NdmCalculations.Cracking; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace DataAccess.DTOs { public class CrackCalculatorFromDTOConvertStrategy : ConvertStrategy { - private IConvertStrategy convertStrategy = new CrackCalculatorInputDataFromDTOConvertStrategy(); + private IConvertStrategy convertStrategy; + private IConvertStrategy ConvertStrategy => convertStrategy ??= new CrackCalculatorInputDataFromDTOConvertStrategy(); public override CrackCalculator GetNewItem(CrackCalculatorDTO source) { - NewItem = new(source.Id); + NewItem = new(source.Id, new ShiftTraceLogger()); NewItem.Name = source.Name; - convertStrategy.ReferenceDictionary = ReferenceDictionary; - convertStrategy.TraceLogger = TraceLogger; - NewItem.InputData = convertStrategy.Convert(source.InputData as CrackCalculatorInputDataDTO); + ConvertStrategy.ReferenceDictionary = ReferenceDictionary; + ConvertStrategy.TraceLogger = TraceLogger; + NewItem.InputData = ConvertStrategy.Convert(source.InputData as CrackCalculatorInputDataDTO); return NewItem; } } diff --git a/StructureHelper/Libraries/LoaderCalculator.dll b/StructureHelper/Libraries/LoaderCalculator.dll index 208cc02..cda100e 100644 Binary files a/StructureHelper/Libraries/LoaderCalculator.dll and b/StructureHelper/Libraries/LoaderCalculator.dll differ diff --git a/StructureHelper/Windows/MainWindow/CrossSections/AnalysisViewModelLogic.cs b/StructureHelper/Windows/MainWindow/CrossSections/AnalysisViewModelLogic.cs index 7bceae7..e6a1076 100644 --- a/StructureHelper/Windows/MainWindow/CrossSections/AnalysisViewModelLogic.cs +++ b/StructureHelper/Windows/MainWindow/CrossSections/AnalysisViewModelLogic.cs @@ -92,7 +92,7 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections private void AddCrackCalculator() { var inputData = new CrackCalculatorInputData(); - var calculator = new CrackCalculator() + var calculator = new CrackCalculator(Guid.NewGuid(), new ShiftTraceLogger()) { Name = "New crack calculator", TraceLogger = new ShiftTraceLogger(), @@ -114,7 +114,7 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections private void AddForceCalculator() { - NewItem = new ForceCalculator() + NewItem = new ForceCalculator(Guid.NewGuid()) { Name = "New force calculator", TraceLogger = new ShiftTraceLogger(), diff --git a/StructureHelperLogics/Models/Materials/Logics/ReinforcementLibUpdateStrategy.cs b/StructureHelperLogics/Models/Materials/Logics/ReinforcementLibUpdateStrategy.cs index 71ad5a8..f7aad13 100644 --- a/StructureHelperLogics/Models/Materials/Logics/ReinforcementLibUpdateStrategy.cs +++ b/StructureHelperLogics/Models/Materials/Logics/ReinforcementLibUpdateStrategy.cs @@ -10,11 +10,12 @@ namespace StructureHelperLogics.Models.Materials public class ReinforcementLibUpdateStrategy : IUpdateStrategy { private IUpdateStrategy libUpdateStrategy; + private IUpdateStrategy LibUpdateStrategy => libUpdateStrategy ??= new LibMaterialUpdateStrategy(); public ReinforcementLibUpdateStrategy(IUpdateStrategy libUpdateStrategy) { this.libUpdateStrategy = libUpdateStrategy; } - public ReinforcementLibUpdateStrategy() : this(new LibMaterialUpdateStrategy()) + public ReinforcementLibUpdateStrategy() { } @@ -23,7 +24,7 @@ namespace StructureHelperLogics.Models.Materials CheckObject.ThrowIfNull(sourceObject); CheckObject.ThrowIfNull(targetObject); if (ReferenceEquals(targetObject, sourceObject)) { return; } - libUpdateStrategy.Update(targetObject, sourceObject); + LibUpdateStrategy.Update(targetObject, sourceObject); } } } diff --git a/StructureHelperLogics/Models/Materials/Logics/SteelLibMaterialUpdateStrategy.cs b/StructureHelperLogics/Models/Materials/Logics/SteelLibMaterialUpdateStrategy.cs index 5201928..bf38906 100644 --- a/StructureHelperLogics/Models/Materials/Logics/SteelLibMaterialUpdateStrategy.cs +++ b/StructureHelperLogics/Models/Materials/Logics/SteelLibMaterialUpdateStrategy.cs @@ -1,9 +1,6 @@ using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Models.Materials; using StructureHelperCommon.Services; -using System; -using System.Collections.Generic; -using System.Text; namespace StructureHelperLogics.Models.Materials { diff --git a/StructureHelperLogics/Models/Templates/CrossSections/CalculatorLogic.cs b/StructureHelperLogics/Models/Templates/CrossSections/CalculatorLogic.cs index caec7f2..fe46d98 100644 --- a/StructureHelperLogics/Models/Templates/CrossSections/CalculatorLogic.cs +++ b/StructureHelperLogics/Models/Templates/CrossSections/CalculatorLogic.cs @@ -32,7 +32,7 @@ namespace StructureHelperLogics.Models.Templates.CrossSections private static ForceCalculator GetForceCalculator() { - return new ForceCalculator() + return new ForceCalculator(Guid.NewGuid()) { Name = "New Force Calculator", TraceLogger = new ShiftTraceLogger() @@ -44,9 +44,9 @@ namespace StructureHelperLogics.Models.Templates.CrossSections var newInputData = new CrackCalculatorInputData(); var checkLogic = new CheckCrackCalculatorInputDataLogic { - InputData = newInputData + Entity = newInputData }; - checkLogic.InputData = newInputData; + checkLogic.Entity = newInputData; var crackCalculator = new CrackCalculator(checkLogic, new CrackCalculatorUpdateStrategy(), null) { Name = "New Crack Calculator", diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs index 7a08fc9..4869ff9 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs @@ -8,14 +8,17 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { public class ForceCalculator : IForceCalculator { - private IUpdateStrategy updateStrategy; - private ICheckInputDataLogic checkInputDataLogic; - private IForceCalculatorLogic forceCalculatorLogic; + private ICheckInputDataLogic? checkInputDataLogic; + private IForceCalculatorLogic? forceCalculatorLogic; + private IUpdateStrategy? updateStrategy; + private ICheckInputDataLogic CheckInputDataLogic => checkInputDataLogic ??= new CheckForceCalculatorInputData(); + private IForceCalculatorLogic ForceCalculatorLogic => forceCalculatorLogic ??= new ForceCalculatorLogic(); + private IUpdateStrategy UpdateStrategy => updateStrategy ??= new ForceCalculatorUpdateStrategy(); /// public Guid Id { get; } = Guid.NewGuid(); /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// public IForceCalculatorInputData InputData { get; set; } = new ForceCalculatorInputData(); /// @@ -37,14 +40,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces this.updateStrategy = updateStrategy; } - public ForceCalculator() : - this(new CheckForceCalculatorInputData(), - new ForceCalculatorLogic(), - new ForceCalculatorUpdateStrategy()) - { - } - - public ForceCalculator(Guid id) : this() + public ForceCalculator(Guid id) { Id = id; } @@ -52,30 +48,30 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces public void Run() { TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service); - checkInputDataLogic.InputData = InputData; - checkInputDataLogic.TraceLogger = TraceLogger; - if (checkInputDataLogic.Check() != true) + CheckInputDataLogic.InputData = InputData; + CheckInputDataLogic.TraceLogger = TraceLogger; + if (CheckInputDataLogic.Check() != true) { Result = new ForceCalculatorResult() { IsValid = false, - Description = checkInputDataLogic.CheckResult + Description = CheckInputDataLogic.CheckResult }; return; } - forceCalculatorLogic.InputData = InputData; + ForceCalculatorLogic.InputData = InputData; if (ActionToOutputResults is not null) { - forceCalculatorLogic.ActionToOutputResults = ActionToOutputResults; + ForceCalculatorLogic.ActionToOutputResults = ActionToOutputResults; } - forceCalculatorLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); - Result = forceCalculatorLogic.GetForcesResults(); + ForceCalculatorLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + Result = ForceCalculatorLogic.GetForcesResults(); } public object Clone() { - var newCalculator = new ForceCalculator(); - updateStrategy.Update(newCalculator, this); + var newCalculator = new ForceCalculator(Guid.NewGuid()); + UpdateStrategy.Update(newCalculator, this); return newCalculator; } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CheckLogics/CheckCrackCalculatorInputDataLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/CheckLogics/CheckCrackCalculatorInputDataLogic.cs index 389fa1b..b28556a 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/CheckLogics/CheckCrackCalculatorInputDataLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/CheckLogics/CheckCrackCalculatorInputDataLogic.cs @@ -3,6 +3,7 @@ using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Models; using StructureHelperCommon.Models.Forces.Logics; using StructureHelperCommon.Models.Loggers; +using StructureHelperLogics.NdmCalculations.Cracking.CheckLogics; using StructureHelperLogics.NdmCalculations.Primitives; using StructureHelperLogics.NdmCalculations.Primitives.Logics; @@ -11,57 +12,65 @@ namespace StructureHelperLogics.NdmCalculations.Cracking /// /// Logic of checking of input data for crack calcultor /// - public class CheckCrackCalculatorInputDataLogic : ICheckInputDataLogic + public class CheckCrackCalculatorInputDataLogic : CheckEntityLogic { private bool result; private ICheckEntityLogic checkPrimitiveCollectionLogic; - - public ICrackCalculatorInputData InputData { get; set; } - - - public string CheckResult { get; private set; } - - public IShiftTraceLogger? TraceLogger { get; set; } + private ICheckEntityLogic> checkMaterialsForCrackingLogic; + private ICheckEntityLogic> CheckMaterialsForCrackingLogic => checkMaterialsForCrackingLogic ??= new PrimitivesForCrackMaterialCheckLogic(); + private ICheckEntityLogic CheckPrimitiveCollectionLogic => checkPrimitiveCollectionLogic ??= new HasPrimitivesCheckLogic() ; public CheckCrackCalculatorInputDataLogic(ICheckEntityLogic checkPrimitiveCollectionLogic) { this.checkPrimitiveCollectionLogic = checkPrimitiveCollectionLogic; } - public CheckCrackCalculatorInputDataLogic() : this (new HasPrimitivesCheckLogic()) + public CheckCrackCalculatorInputDataLogic() { } - public bool Check() + public override bool Check() { TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Debug); result = true; CheckResult = string.Empty; + CheckCrackingMaterials(); CheckPrimitives(); CheckActions(); return result; } + private void CheckCrackingMaterials() + { + CheckMaterialsForCrackingLogic.TraceLogger = TraceLogger; + CheckMaterialsForCrackingLogic.Entity = Entity.Primitives; + if (CheckMaterialsForCrackingLogic.Check() == false) + { + result = false; + CheckResult += CheckMaterialsForCrackingLogic.CheckResult; + } + } + private void CheckPrimitives() { - if (checkPrimitiveCollectionLogic is null) + if (CheckPrimitiveCollectionLogic is null) { throw new StructureHelperException(ErrorStrings.ParameterIsNull + ": check primitive logic"); } - checkPrimitiveCollectionLogic.Entity = InputData; - checkPrimitiveCollectionLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(); - if (checkPrimitiveCollectionLogic.Check() == false) + CheckPrimitiveCollectionLogic.Entity = Entity; + CheckPrimitiveCollectionLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(); + if (CheckPrimitiveCollectionLogic.Check() == false) { result = false; - CheckResult += checkPrimitiveCollectionLogic.CheckResult; - TraceLogger?.AddMessage(checkPrimitiveCollectionLogic.CheckResult, TraceLogStatuses.Error); + CheckResult += CheckPrimitiveCollectionLogic.CheckResult; + TraceLogger?.AddMessage(CheckPrimitiveCollectionLogic.CheckResult, TraceLogStatuses.Error); } } private void CheckActions() { - if (InputData.ForceActions is null || (!InputData.ForceActions.Any())) + if (Entity.ForceActions is null || (!Entity.ForceActions.Any())) { result = false; string message = "Calculator does not contain any actions\n"; @@ -71,7 +80,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking }; var checkLogic = new CheckForceActionsLogic(TraceLogger) { - Entity = InputData.ForceActions + Entity = Entity.ForceActions }; if (checkLogic.Check() == false) { @@ -84,7 +93,5 @@ namespace StructureHelperLogics.NdmCalculations.Cracking CheckResult += errorString + "\n"; TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); } - - } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CheckLogics/PrimitivesForCrackMaterialCheckLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/CheckLogics/PrimitivesForCrackMaterialCheckLogic.cs new file mode 100644 index 0000000..919ecaa --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CheckLogics/PrimitivesForCrackMaterialCheckLogic.cs @@ -0,0 +1,40 @@ +using LoaderCalculator.Data.Materials; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperLogics.NdmCalculations.Primitives; + +namespace StructureHelperLogics.NdmCalculations.Cracking.CheckLogics +{ + /// + /// Checks whether a collection of NDM primitives contains + /// at least one material that supports crack appearance. + /// + public class PrimitivesForCrackMaterialCheckLogic + : CheckEntityLogic> + { + public override bool Check() + { + if (Entity is null) + { + TraceMessage("Collection of primitives is null"); + return false; + } + + CheckResult = string.Empty; + + bool hasCrackMaterial = Entity.Any(primitive => + primitive?.NdmElement?.HeadMaterial? + .GetLoaderMaterial(LimitStates.SLS, CalcTerms.ShortTerm) + is ICrackMaterial); + + if (!hasCrackMaterial) + { + TraceMessage( + "Collection of primitives does not have material which supports cracking"); + } + + return hasCrackMaterial; + } + } +} + diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs index c7bf105..b99da36 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs @@ -1,18 +1,11 @@ using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Infrastructures.Interfaces; -using StructureHelperCommon.Infrastructures.Settings; using StructureHelperCommon.Models; using StructureHelperCommon.Models.Calculators; -using StructureHelperCommon.Models.Forces; using StructureHelperCommon.Models.Loggers; using StructureHelperLogics.Models.Materials; using StructureHelperLogics.NdmCalculations.Analyses.ByForces; using StructureHelperLogics.NdmCalculations.Primitives; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { @@ -24,20 +17,24 @@ namespace StructureHelperLogics.NdmCalculations.Cracking const CalcTerms shortTerm = CalcTerms.ShortTerm; private const double maxSizeOfCrossSection = 1d; private CrackResult result; + private IGetTupleInputDatasLogic datasLogic; + + private ICheckEntityLogic checkInputDataLogic; private IUpdateStrategy updateStrategy; - private ICheckInputDataLogic checkInputDataLogic; + private ICheckEntityLogic CheckInputDataLogic => checkInputDataLogic ??= new CheckCrackCalculatorInputDataLogic(); + private IUpdateStrategy UpdateStrategy => updateStrategy ??= new CrackCalculatorUpdateStrategy(); public Guid Id { get; } = Guid.NewGuid(); - public string Name { get; set; } + public string Name { get; set; } = string.Empty; public ICrackCalculatorInputData InputData { get; set; } public IResult Result => result; public IShiftTraceLogger? TraceLogger { get; set; } public bool ShowTraceData { get; set; } - public CrackCalculator(ICheckInputDataLogic checkInputDataLogic, + public CrackCalculator(ICheckEntityLogic checkInputDataLogic, IUpdateStrategy updateStrategy, IShiftTraceLogger traceLogger ) @@ -45,18 +42,12 @@ namespace StructureHelperLogics.NdmCalculations.Cracking this.checkInputDataLogic = checkInputDataLogic; this.updateStrategy = updateStrategy; this.TraceLogger = traceLogger; - Name = string.Empty; } - public CrackCalculator() - : this(new CheckCrackCalculatorInputDataLogic(), - new CrackCalculatorUpdateStrategy(), - new ShiftTraceLogger()) - { } - - public CrackCalculator(Guid id) : this() + public CrackCalculator(Guid id, IShiftTraceLogger traceLogger) { Id = id; + TraceLogger = traceLogger; } public object Clone() @@ -64,18 +55,21 @@ namespace StructureHelperLogics.NdmCalculations.Cracking CrackCalculatorInputData crackInputData = new CrackCalculatorInputData(); var checkDataLogic = new CheckCrackCalculatorInputDataLogic() { - InputData = InputData + Entity = InputData }; var newItem = new CrackCalculator(checkDataLogic, new CrackCalculatorUpdateStrategy(), new ShiftTraceLogger()); newItem.InputData = crackInputData; - updateStrategy.Update(newItem, this); + UpdateStrategy.Update(newItem, this); return newItem; } public void Run() { PrepareNewResult(); - CheckInputData(); + if (CheckInputData() == false) + { + return; + } TraceInputData(); try { @@ -115,15 +109,17 @@ namespace StructureHelperLogics.NdmCalculations.Cracking traceLogic.AddEntriesToTraceLogger(TraceLogger); } - private void CheckInputData() + private bool CheckInputData() { - checkInputDataLogic.InputData = InputData; - checkInputDataLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); - if (checkInputDataLogic.Check() == false) + CheckInputDataLogic.Entity = InputData; + CheckInputDataLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + if (CheckInputDataLogic.Check() == false) { result.IsValid = false; - result.Description += checkInputDataLogic.CheckResult; + result.Description += CheckInputDataLogic.CheckResult; + return false; } + return true; } private void ProcessCalculations() diff --git a/StructureHelperLogics/Services/NdmCalculations/InterpolateService.cs b/StructureHelperLogics/Services/NdmCalculations/InterpolateService.cs index 5726dd7..7bf72e7 100644 --- a/StructureHelperLogics/Services/NdmCalculations/InterpolateService.cs +++ b/StructureHelperLogics/Services/NdmCalculations/InterpolateService.cs @@ -13,7 +13,7 @@ namespace StructureHelperLogics.Services.NdmCalculations private static IForceTupleServiceLogic ForceTupleServiceLogic => forceTupleServiceLogic ??= new ForceTupleServiceLogic(); public static ForceCalculator InterpolateForceCalculator(IForceCalculator source, IStateCalcTermPair stateCalcTermPair, InterpolateTuplesResult interpolateTuplesResult) { - ForceCalculator calculator = new ForceCalculator(); + ForceCalculator calculator = new ForceCalculator(Guid.NewGuid()); calculator.InputData.LimitStatesList.Clear(); calculator.InputData.LimitStatesList.Add(stateCalcTermPair.LimitState); calculator.InputData.CalcTermsList.Clear(); diff --git a/StructureHelperTests/UnitTests/MaterialTests/ConcreteLibUpdateStrategyTests.cs b/StructureHelperTests/UnitTests/MaterialTests/ConcreteLibUpdateStrategyTests.cs new file mode 100644 index 0000000..aff0cb8 --- /dev/null +++ b/StructureHelperTests/UnitTests/MaterialTests/ConcreteLibUpdateStrategyTests.cs @@ -0,0 +1,92 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Materials; +using StructureHelperLogics.Models.Materials; + +namespace StructureHelperTests.UnitTests.MaterialTests +{ + + + [TestFixture] + public class ConcreteLibUpdateStrategyTests + { + private Mock> libUpdateStrategyMock; + private ConcreteLibUpdateStrategy strategy; + + [SetUp] + public void SetUp() + { + libUpdateStrategyMock = new Mock>(); + strategy = new ConcreteLibUpdateStrategy(libUpdateStrategyMock.Object); + } + + [Test] + public void Update_SourceIsNull_Throws() + { + // Arrange + var target = new Mock().Object; + + // Act & Assert + Assert.Throws(() => + strategy.Update(target, null)); + } + + [Test] + public void Update_TargetIsNull_Throws() + { + // Arrange + var source = new Mock().Object; + + // Act & Assert + Assert.Throws(() => + strategy.Update(null, source)); + } + + [Test] + public void Update_SourceAndTargetAreSameInstance_DoesNothing() + { + // Arrange + var materialMock = new Mock(); + + // Act + strategy.Update(materialMock.Object, materialMock.Object); + + // Assert + libUpdateStrategyMock.Verify( + x => x.Update(It.IsAny(), It.IsAny()), + Times.Never); + } + + [Test] + public void Update_ValidObjects_UpdatesLibMaterialAndConcreteProperties() + { + // Arrange + var sourceMock = new Mock(); + var targetMock = new Mock(); + + sourceMock.SetupGet(x => x.TensionForULS).Returns(false); + sourceMock.SetupGet(x => x.TensionForSLS).Returns(true); + sourceMock.SetupGet(x => x.RelativeHumidity).Returns(0.65); + sourceMock.SetupGet(x => x.MinAge).Returns(7); + sourceMock.SetupGet(x => x.MaxAge).Returns(365); + + // Act + strategy.Update(targetMock.Object, sourceMock.Object); + + // Assert — lib material delegation + libUpdateStrategyMock.Verify( + x => x.Update(targetMock.Object, sourceMock.Object), + Times.Once); + + // Assert — concrete-specific properties copied + targetMock.VerifySet(x => x.TensionForULS = false, Times.Once); + targetMock.VerifySet(x => x.TensionForSLS = true, Times.Once); + targetMock.VerifySet(x => x.RelativeHumidity = 0.65, Times.Once); + targetMock.VerifySet(x => x.MinAge = 7, Times.Once); + targetMock.VerifySet(x => x.MaxAge = 365, Times.Once); + } + } + +} diff --git a/StructureHelperTests/UnitTests/MaterialTests/PrimitivesForCrackMaterialCheckLogicTests.cs b/StructureHelperTests/UnitTests/MaterialTests/PrimitivesForCrackMaterialCheckLogicTests.cs new file mode 100644 index 0000000..24c8e0c --- /dev/null +++ b/StructureHelperTests/UnitTests/MaterialTests/PrimitivesForCrackMaterialCheckLogicTests.cs @@ -0,0 +1,116 @@ +using LoaderCalculator.Data.Materials; +using Moq; +using NUnit.Framework; +using StructureHelper.Models.Materials; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models; +using StructureHelperLogics.NdmCalculations.Cracking.CheckLogics; +using StructureHelperLogics.NdmCalculations.Primitives; +using System.Collections.Generic; + +namespace StructureHelperTests.UnitTests.MaterialTests +{ + [TestFixture] + public class PrimitivesForCrackMaterialCheckLogicTests + { + private Mock traceLoggerMock; + private PrimitivesForCrackMaterialCheckLogic logic; + + [SetUp] + public void SetUp() + { + traceLoggerMock = new Mock(); + + logic = new PrimitivesForCrackMaterialCheckLogic + { + TraceLogger = traceLoggerMock.Object + }; + } + + [Test] + public void Check_EntityIsNull_ReturnsFalseAndTraces() + { + // Arrange + logic.Entity = null; + + // Act + bool result = logic.Check(); + + // Assert + Assert.That(result, Is.False); + Assert.That(logic.CheckResult, Is.Not.Empty); + + traceLoggerMock.Verify( + x => x.AddMessage(It.IsAny()), + Times.AtLeastOnce); + } + + [Test] + public void Check_NoCrackMaterial_ReturnsFalseAndTraces() + { + // Arrange + logic.Entity = new[] + { + CreatePrimitive(new Mock().Object), + CreatePrimitive(new Mock().Object) + }; + + // Act + bool result = logic.Check(); + + // Assert + Assert.That(result, Is.False); + Assert.That(logic.CheckResult, Does.Contain("supports cracking")); + + traceLoggerMock.Verify( + x => x.AddMessage(It.IsAny()), + Times.Once); + } + + [Test] + public void Check_WithCrackMaterial_ReturnsTrueAndDoesNotTrace() + { + // Arrange + logic.Entity = new[] + { + CreatePrimitive(new Mock().Object), + CreatePrimitive(new Mock().Object) + }; + + // Act + bool result = logic.Check(); + + // Assert + Assert.That(result, Is.True); + Assert.That(logic.CheckResult, Is.Empty); + + traceLoggerMock.Verify( + x => x.AddMessage(It.IsAny()), + Times.Never); + } + + // ---------- helper ---------- + + private static INdmPrimitive CreatePrimitive(IMaterial material) + { + var headMaterialMock = new Mock(); + headMaterialMock + .Setup(x => x.GetLoaderMaterial(LimitStates.SLS, CalcTerms.ShortTerm)) + .Returns(material); + + var ndmElementMock = new Mock(); + ndmElementMock + .SetupGet(x => x.HeadMaterial) + .Returns(headMaterialMock.Object); + + var primitiveMock = new Mock(); + primitiveMock + .SetupGet(x => x.NdmElement) + .Returns(ndmElementMock.Object); + + return primitiveMock.Object; + } + } + + +} diff --git a/StructureHelperTests/UnitTests/MaterialTests/ReinforcementLibUpdateStrategyTests.cs b/StructureHelperTests/UnitTests/MaterialTests/ReinforcementLibUpdateStrategyTests.cs new file mode 100644 index 0000000..dec4b22 --- /dev/null +++ b/StructureHelperTests/UnitTests/MaterialTests/ReinforcementLibUpdateStrategyTests.cs @@ -0,0 +1,78 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Materials; +using StructureHelperLogics.Models.Materials; + +namespace StructureHelperTests.UnitTests.MaterialTests +{ + + [TestFixture] + public class ReinforcementLibUpdateStrategyTests + { + private Mock> libUpdateStrategyMock; + private ReinforcementLibUpdateStrategy strategy; + + [SetUp] + public void SetUp() + { + libUpdateStrategyMock = new Mock>(); + strategy = new ReinforcementLibUpdateStrategy(libUpdateStrategyMock.Object); + } + + [Test] + public void Update_SourceIsNull_Throws() + { + // Arrange + var target = new Mock().Object; + + // Act & Assert + Assert.Throws(() => + strategy.Update(target, null)); + } + + [Test] + public void Update_TargetIsNull_Throws() + { + // Arrange + var source = new Mock().Object; + + // Act & Assert + Assert.Throws(() => + strategy.Update(null, source)); + } + + [Test] + public void Update_SourceAndTargetAreSameInstance_DoesNothing() + { + // Arrange + var materialMock = new Mock(); + + // Act + strategy.Update(materialMock.Object, materialMock.Object); + + // Assert + libUpdateStrategyMock.Verify( + x => x.Update(It.IsAny(), It.IsAny()), + Times.Never); + } + + [Test] + public void Update_ValidObjects_DelegatesToLibMaterialUpdateStrategy() + { + // Arrange + var sourceMock = new Mock(); + var targetMock = new Mock(); + + // Act + strategy.Update(targetMock.Object, sourceMock.Object); + + // Assert + libUpdateStrategyMock.Verify( + x => x.Update(targetMock.Object, sourceMock.Object), + Times.Once); + } + } + +} diff --git a/StructureHelperTests/UnitTests/MaterialTests/SteelLibMaterialUpdateStrategyTests.cs b/StructureHelperTests/UnitTests/MaterialTests/SteelLibMaterialUpdateStrategyTests.cs new file mode 100644 index 0000000..6509bd4 --- /dev/null +++ b/StructureHelperTests/UnitTests/MaterialTests/SteelLibMaterialUpdateStrategyTests.cs @@ -0,0 +1,95 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Materials; +using StructureHelperLogics.Models.Materials; + +namespace StructureHelperTests.UnitTests.MaterialTests +{ + + + [TestFixture] + public class SteelLibMaterialUpdateStrategyTests + { + private Mock> libUpdateStrategyMock; + private SteelLibMaterialUpdateStrategy strategy; + + [SetUp] + public void SetUp() + { + libUpdateStrategyMock = new Mock>(); + strategy = new SteelLibMaterialUpdateStrategy(libUpdateStrategyMock.Object); + } + + [Test] + public void Update_SourceIsNull_Throws() + { + // Arrange + var target = new Mock().Object; + + // Act & Assert + Assert.Throws(() => + strategy.Update(target, null)); + } + + [Test] + public void Update_TargetIsNull_Throws() + { + // Arrange + var source = new Mock().Object; + + // Act & Assert + Assert.Throws(() => + strategy.Update(null, source)); + } + + [Test] + public void Update_SourceAndTargetAreSameInstance_DoesNothing() + { + // Arrange + var materialMock = new Mock(); + + // Act + strategy.Update(materialMock.Object, materialMock.Object); + + // Assert + libUpdateStrategyMock.Verify( + x => x.Update(It.IsAny(), It.IsAny()), + Times.Never); + + materialMock.VerifySet(x => x.MaxPlasticStrainRatio = It.IsAny(), Times.Never); + materialMock.VerifySet(x => x.UlsFactor = It.IsAny(), Times.Never); + materialMock.VerifySet(x => x.ThicknessFactor = It.IsAny(), Times.Never); + materialMock.VerifySet(x => x.WorkConditionFactor = It.IsAny(), Times.Never); + } + + [Test] + public void Update_ValidObjects_UpdatesLibMaterialAndSteelProperties() + { + // Arrange + var sourceMock = new Mock(); + var targetMock = new Mock(); + + sourceMock.SetupGet(x => x.MaxPlasticStrainRatio).Returns(1.1); + sourceMock.SetupGet(x => x.UlsFactor).Returns(1.2); + sourceMock.SetupGet(x => x.ThicknessFactor).Returns(1.3); + sourceMock.SetupGet(x => x.WorkConditionFactor).Returns(1.4); + + // Act + strategy.Update(targetMock.Object, sourceMock.Object); + + // Assert — lib material update + libUpdateStrategyMock.Verify( + x => x.Update(targetMock.Object, sourceMock.Object), + Times.Once); + + // Assert — steel-specific properties + targetMock.VerifySet(x => x.MaxPlasticStrainRatio = 1.1, Times.Once); + targetMock.VerifySet(x => x.UlsFactor = 1.2, Times.Once); + targetMock.VerifySet(x => x.ThicknessFactor = 1.3, Times.Once); + targetMock.VerifySet(x => x.WorkConditionFactor = 1.4, Times.Once); + } + } + +} diff --git a/StructureHelperTests/UnitTests/UpdateStrategiesTests/ConcreteLibUpdateStrategyTests.cs b/StructureHelperTests/UnitTests/UpdateStrategiesTests/ConcreteLibUpdateStrategyTests.cs deleted file mode 100644 index e508f0a..0000000 --- a/StructureHelperTests/UnitTests/UpdateStrategiesTests/ConcreteLibUpdateStrategyTests.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Moq; -using NUnit.Framework; -using StructureHelperCommon.Infrastructures.Exceptions; -using StructureHelperCommon.Infrastructures.Interfaces; -using StructureHelperCommon.Models.Materials; -using StructureHelperLogics.Models.Materials; -using System; - -namespace StructureHelperTests.UnitTests.UpdateStrategiesTests -{ - - - namespace YourNamespace.Tests - { - [TestFixture] - public class ConcreteLibUpdateStrategyTests - { - private Mock> mockLibUpdateStrategy; - private ConcreteLibUpdateStrategy strategy; - - [SetUp] - public void Setup() - { - mockLibUpdateStrategy = new Mock>(); - strategy = new ConcreteLibUpdateStrategy(mockLibUpdateStrategy.Object); - } - - [Test] - public void Update_ShouldUpdateTargetObject_WhenSourceAndTargetAreNotTheSame() - { - // Arrange - var targetMock = new Mock(); - var sourceMock = new Mock(); - - sourceMock.Setup(s => s.TensionForULS).Returns(false); - sourceMock.Setup(s => s.TensionForSLS).Returns(true); - sourceMock.Setup(s => s.RelativeHumidity).Returns(0.75); - - // Act - strategy.Update(targetMock.Object, sourceMock.Object); - - // Assert - mockLibUpdateStrategy.Verify(l => l.Update(targetMock.Object, sourceMock.Object), Times.Once); - targetMock.VerifySet(t => t.TensionForULS = false); - targetMock.VerifySet(t => t.TensionForSLS = true); - targetMock.VerifySet(t => t.RelativeHumidity = 0.75); - } - - [Test] - public void Update_ShouldNotUpdate_WhenSourceAndTargetAreSame() - { - // Arrange - var targetMock = new Mock(); - - // Act - strategy.Update(targetMock.Object, targetMock.Object); - - // Assert - mockLibUpdateStrategy.Verify(l => l.Update(It.IsAny(), It.IsAny()), Times.Never); - targetMock.VerifySet(t => t.TensionForULS = It.IsAny(), Times.Never); - targetMock.VerifySet(t => t.TensionForSLS = It.IsAny(), Times.Never); - targetMock.VerifySet(t => t.RelativeHumidity = It.IsAny(), Times.Never); - } - } - } - -}