Add calculators cloning logic
This commit is contained in:
@@ -34,14 +34,14 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
|
|||||||
private int stepCount;
|
private int stepCount;
|
||||||
|
|
||||||
private static GeometryNames GeometryNames => ProgramSetting.GeometryNames;
|
private static GeometryNames GeometryNames => ProgramSetting.GeometryNames;
|
||||||
public LimitCurvesCalculatorInputData InputData { get; set; }
|
public ILimitCurvesCalculatorInputData InputData { get; set; }
|
||||||
public int StepCount { get => stepCount; set => stepCount = value; }
|
public int StepCount { get => stepCount; set => stepCount = value; }
|
||||||
|
|
||||||
public Action<int> SetProgress { get; set; }
|
public Action<int> SetProgress { get; set; }
|
||||||
public bool Result { get; set; }
|
public bool Result { get; set; }
|
||||||
public IShiftTraceLogger? TraceLogger { get; set; }
|
public IShiftTraceLogger? TraceLogger { get; set; }
|
||||||
|
|
||||||
public InteractionDiagramLogic(LimitCurvesCalculatorInputData inputData)
|
public InteractionDiagramLogic(ILimitCurvesCalculatorInputData inputData)
|
||||||
{
|
{
|
||||||
InputData = inputData;
|
InputData = inputData;
|
||||||
stepCount = InputData.PointCount;
|
stepCount = InputData.PointCount;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
|
|||||||
{
|
{
|
||||||
public class LimitCurveDataViewModel : OkCancelViewModelBase, IDataErrorInfo
|
public class LimitCurveDataViewModel : OkCancelViewModelBase, IDataErrorInfo
|
||||||
{
|
{
|
||||||
private LimitCurvesCalculatorInputData inputData;
|
private ILimitCurvesCalculatorInputData inputData;
|
||||||
|
|
||||||
|
|
||||||
//public SurroundDataViewModel SurroundDataViewModel { get; private set; }
|
//public SurroundDataViewModel SurroundDataViewModel { get; private set; }
|
||||||
@@ -52,7 +52,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu
|
|||||||
|
|
||||||
public IEnumerable<INdmPrimitive> AllowedPrimitives { get; set; }
|
public IEnumerable<INdmPrimitive> AllowedPrimitives { get; set; }
|
||||||
|
|
||||||
public LimitCurveDataViewModel(LimitCurvesCalculatorInputData inputData, IEnumerable<INdmPrimitive> allowedPrimitives)
|
public LimitCurveDataViewModel(ILimitCurvesCalculatorInputData inputData, IEnumerable<INdmPrimitive> allowedPrimitives)
|
||||||
{
|
{
|
||||||
this.inputData = inputData;
|
this.inputData = inputData;
|
||||||
AllowedPrimitives = allowedPrimitives;
|
AllowedPrimitives = allowedPrimitives;
|
||||||
|
|||||||
@@ -5,35 +5,48 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:StructureHelper.Windows.CalculationWindows.CalculatorsViews.GeometryCalculatorViews"
|
xmlns:local="clr-namespace:StructureHelper.Windows.CalculationWindows.CalculatorsViews.GeometryCalculatorViews"
|
||||||
xmlns:vm="clr-namespace:StructureHelper.Windows.ViewModels.Calculations.Calculators.GeometryCalculatorVMs"
|
xmlns:vm="clr-namespace:StructureHelper.Windows.ViewModels.Calculations.Calculators.GeometryCalculatorVMs"
|
||||||
|
xmlns:uc="clr-namespace:StructureHelper.Windows.UserControls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DataContext="{d:DesignInstance vm:GeometryCalculatorResultViewModel}"
|
d:DataContext="{d:DesignInstance vm:GeometryCalculatorResultViewModel}"
|
||||||
Title="Geometry Properties" Height="450" Width="850" WindowStartupLocation="CenterScreen">
|
Title="Geometry Properties" Height="450" Width="850" WindowStartupLocation="CenterScreen">
|
||||||
<Grid>
|
<DockPanel>
|
||||||
<Grid.ColumnDefinitions>
|
<ToolBarTray DockPanel.Dock="Top">
|
||||||
<ColumnDefinition/>
|
<ToolBar>
|
||||||
<ColumnDefinition Width="90"/>
|
<Button Style="{DynamicResource ToolButton}" Command="{Binding ExportToCSVCommand}">
|
||||||
</Grid.ColumnDefinitions>
|
<Button.ToolTip>
|
||||||
<DataGrid x:Name="ResultGrid" IsReadOnly="True" AutoGenerateColumns="False" ItemsSource="{Binding TextParameters}">
|
<uc:ButtonToolTipEh HeaderText="Export to *.csv"
|
||||||
<DataGrid.RowStyle>
|
IconContent="{StaticResource ExportToXLS}"
|
||||||
<Style TargetType="DataGridRow">
|
DescriptionText="Export all valid results to *.csv file"/>
|
||||||
<Style.Triggers>
|
</Button.ToolTip>
|
||||||
<DataTrigger Binding="{Binding IsValid}" Value="false">
|
<Viewbox>
|
||||||
<Setter Property="Background" Value="Pink"/>
|
<ContentControl ContentTemplate="{DynamicResource ExportToXLS}"/>
|
||||||
</DataTrigger>
|
</Viewbox>
|
||||||
</Style.Triggers>
|
</Button>
|
||||||
</Style>
|
</ToolBar>
|
||||||
</DataGrid.RowStyle>
|
</ToolBarTray>
|
||||||
<DataGrid.Columns>
|
<Grid>
|
||||||
<DataGridCheckBoxColumn Header="Valid" Binding="{Binding Path=IsValid}"/>
|
<Grid.ColumnDefinitions>
|
||||||
<DataGridTextColumn Header="Name" Width="100" Binding="{Binding Name}"/>
|
<ColumnDefinition/>
|
||||||
<DataGridTextColumn Header="Short" Width="50" Binding="{Binding ShortName}"/>
|
</Grid.ColumnDefinitions>
|
||||||
<DataGridTextColumn Header="Unit" Width="100" Binding="{Binding Text}"/>
|
<DataGrid x:Name="ResultGrid" IsReadOnly="True" AutoGenerateColumns="False" ItemsSource="{Binding TextParameters}">
|
||||||
<DataGridTextColumn Header="Value" Width="150" Binding="{Binding Value}"/>
|
<DataGrid.RowStyle>
|
||||||
<DataGridTextColumn Header="Description" Width="400" Binding="{Binding Description}"/>
|
<Style TargetType="DataGridRow">
|
||||||
</DataGrid.Columns>
|
<Style.Triggers>
|
||||||
</DataGrid>
|
<DataTrigger Binding="{Binding IsValid}" Value="false">
|
||||||
<StackPanel Grid.Column="1">
|
<Setter Property="Background" Value="Pink"/>
|
||||||
<Button Margin="3" Content="Export" ToolTip="Export results to *.csv" Command="{Binding ExportToCSVCommand}"/>
|
</DataTrigger>
|
||||||
</StackPanel>
|
</Style.Triggers>
|
||||||
</Grid>
|
</Style>
|
||||||
|
</DataGrid.RowStyle>
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridCheckBoxColumn Header="Valid" Binding="{Binding Path=IsValid}"/>
|
||||||
|
<DataGridTextColumn Header="Name" Width="100" Binding="{Binding Name}"/>
|
||||||
|
<DataGridTextColumn Header="Short" Width="50" Binding="{Binding ShortName}"/>
|
||||||
|
<DataGridTextColumn Header="Unit" Width="100" Binding="{Binding Text}"/>
|
||||||
|
<DataGridTextColumn Header="Value" Width="150" Binding="{Binding Value}"/>
|
||||||
|
<DataGridTextColumn Header="Description" Width="400" Binding="{Binding Description}"/>
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
</Grid>
|
||||||
|
</DockPanel>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@@ -8,10 +8,14 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace StructureHelperCommon.Infrastructures.Interfaces
|
namespace StructureHelperCommon.Infrastructures.Interfaces
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates deep copy of object by dictionary (if copy of object is not created it create copy, otherwise take copy from dictionary)
|
||||||
|
/// </summary>
|
||||||
public class DeepCloningStrategy : ICloningStrategy
|
public class DeepCloningStrategy : ICloningStrategy
|
||||||
{
|
{
|
||||||
private readonly Dictionary<object, object> _clonedObjects = new Dictionary<object, object>();
|
private readonly Dictionary<object, object> _clonedObjects = new();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public T Clone<T>(T original, ICloneStrategy<T>? cloneStrategy = null) where T : class
|
public T Clone<T>(T original, ICloneStrategy<T>? cloneStrategy = null) where T : class
|
||||||
{
|
{
|
||||||
if (original == null) return null;
|
if (original == null) return null;
|
||||||
@@ -40,21 +44,6 @@ namespace StructureHelperCommon.Infrastructures.Interfaces
|
|||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
//private T CreateClone<T>(T original) where T : class
|
|
||||||
//{
|
|
||||||
// // Example logic for creating a clone (modify as needed for your use case)
|
|
||||||
// var type = original.GetType();
|
|
||||||
// var clone = Activator.CreateInstance(type);
|
|
||||||
|
|
||||||
// foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
|
|
||||||
// {
|
|
||||||
// var value = field.GetValue(original);
|
|
||||||
// field.SetValue(clone, Clone(value));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return (T)clone;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,18 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace StructureHelperCommon.Infrastructures.Interfaces
|
namespace StructureHelperCommon.Infrastructures.Interfaces
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for cloning objects
|
||||||
|
/// </summary>
|
||||||
public interface ICloningStrategy
|
public interface ICloningStrategy
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns copy of object
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of object</typeparam>
|
||||||
|
/// <param name="original">Source object</param>
|
||||||
|
/// <param name="cloneStrategy">Strategy for cloning of object of specified type</param>
|
||||||
|
/// <returns></returns>
|
||||||
T Clone<T>(T original, ICloneStrategy<T>? cloneStrategy = null) where T : class;
|
T Clone<T>(T original, ICloneStrategy<T>? cloneStrategy = null) where T : class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,8 +42,7 @@ namespace StructureHelperLogics.Models.CrossSections
|
|||||||
new HasMaterialsUpdateCloningStrategy(null),
|
new HasMaterialsUpdateCloningStrategy(null),
|
||||||
new HasPrimitivesUpdateCloningStrategy(null),
|
new HasPrimitivesUpdateCloningStrategy(null),
|
||||||
new HasCalculatorsUpdateCloningStrategy(null))
|
new HasCalculatorsUpdateCloningStrategy(null))
|
||||||
{
|
{
|
||||||
|
|
||||||
forcesUpdateStrategy = new HasForceActionUpdateCloningStrategy(cloningStrategy);
|
forcesUpdateStrategy = new HasForceActionUpdateCloningStrategy(cloningStrategy);
|
||||||
materialsUpdateStrategy = new HasMaterialsUpdateCloningStrategy(cloningStrategy);
|
materialsUpdateStrategy = new HasMaterialsUpdateCloningStrategy(cloningStrategy);
|
||||||
primitivesUpdateStrategy = new HasPrimitivesUpdateCloningStrategy(cloningStrategy);
|
primitivesUpdateStrategy = new HasPrimitivesUpdateCloningStrategy(cloningStrategy);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
|
|||||||
{
|
{
|
||||||
public interface ILimitCurvesCalculator : ISaveable, ICalculator, IHasActionByResult
|
public interface ILimitCurvesCalculator : ISaveable, ICalculator, IHasActionByResult
|
||||||
{
|
{
|
||||||
LimitCurvesCalculatorInputData InputData { get; set; }
|
ILimitCurvesCalculatorInputData InputData { get; set; }
|
||||||
string Name { get; set; }
|
string Name { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
|
|||||||
|
|
||||||
public Guid Id { get; }
|
public Guid Id { get; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public LimitCurvesCalculatorInputData InputData { get; set; }
|
public ILimitCurvesCalculatorInputData InputData { get; set; }
|
||||||
public IResult Result => result;
|
public IResult Result => result;
|
||||||
|
|
||||||
public Action<IResult> ActionToOutputResults { get; set; }
|
public Action<IResult> ActionToOutputResults { get; set; }
|
||||||
@@ -30,7 +30,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
|
|||||||
public LimitCurvesCalculator()
|
public LimitCurvesCalculator()
|
||||||
{
|
{
|
||||||
Name = "New calculator";
|
Name = "New calculator";
|
||||||
InputData = new();
|
InputData = new LimitCurvesCalculatorInputData();
|
||||||
}
|
}
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve
|
|||||||
if (ReferenceEquals(targetObject, sourceObject)) { return; }
|
if (ReferenceEquals(targetObject, sourceObject)) { return; }
|
||||||
targetObject.LimitStates.Clear();
|
targetObject.LimitStates.Clear();
|
||||||
targetObject.CalcTerms.Clear();
|
targetObject.CalcTerms.Clear();
|
||||||
|
targetObject.PrimitiveSeries.Clear();
|
||||||
targetObject.PredicateEntries.Clear();
|
targetObject.PredicateEntries.Clear();
|
||||||
targetObject.LimitStates.AddRange(sourceObject.LimitStates);
|
targetObject.LimitStates.AddRange(sourceObject.LimitStates);
|
||||||
targetObject.CalcTerms.AddRange(sourceObject.CalcTerms);
|
targetObject.CalcTerms.AddRange(sourceObject.CalcTerms);
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||||
|
using StructureHelperCommon.Models.Parameters;
|
||||||
|
using StructureHelperCommon.Services;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Primitives;
|
||||||
|
|
||||||
|
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates deep copy of limit curves calculator
|
||||||
|
/// </summary>
|
||||||
|
public class LimitCurvesCalculatorUpdateCloningStrategy : IUpdateStrategy<ILimitCurvesCalculator>
|
||||||
|
{
|
||||||
|
private ICloningStrategy cloningStrategy;
|
||||||
|
private IUpdateStrategy<ILimitCurvesCalculatorInputData> limitCurvesInputDataUpdateStrategy;
|
||||||
|
|
||||||
|
public LimitCurvesCalculatorUpdateCloningStrategy(ICloningStrategy cloningStrategy) : this (
|
||||||
|
cloningStrategy,
|
||||||
|
new LimitCurvesCalculatorInputDataUpdateStrategy())
|
||||||
|
{
|
||||||
|
this.cloningStrategy = cloningStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LimitCurvesCalculatorUpdateCloningStrategy(
|
||||||
|
ICloningStrategy cloningStrategy,
|
||||||
|
IUpdateStrategy<ILimitCurvesCalculatorInputData> limitCurvesInputDataUpdateStrategy)
|
||||||
|
{
|
||||||
|
this.cloningStrategy = cloningStrategy;
|
||||||
|
this.limitCurvesInputDataUpdateStrategy = limitCurvesInputDataUpdateStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(ILimitCurvesCalculator targetObject, ILimitCurvesCalculator sourceObject)
|
||||||
|
{
|
||||||
|
CheckObject.IsNull(cloningStrategy);
|
||||||
|
CheckObject.IsNull(sourceObject);
|
||||||
|
CheckObject.IsNull(targetObject);
|
||||||
|
if (ReferenceEquals(targetObject, sourceObject)) { return; }
|
||||||
|
var targetData = targetObject.InputData;
|
||||||
|
limitCurvesInputDataUpdateStrategy.Update(targetData, sourceObject.InputData);
|
||||||
|
foreach (var series in targetData.PrimitiveSeries)
|
||||||
|
{
|
||||||
|
List<INdmPrimitive> collection = UpdatePrimitivesCollection(series);
|
||||||
|
series.Collection.AddRange(collection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<INdmPrimitive> UpdatePrimitivesCollection(NamedCollection<INdmPrimitive> series)
|
||||||
|
{
|
||||||
|
List<INdmPrimitive> collection = new();
|
||||||
|
foreach (var item in series.Collection)
|
||||||
|
{
|
||||||
|
var newItem = cloningStrategy.Clone(item);
|
||||||
|
collection.Add(newItem);
|
||||||
|
}
|
||||||
|
series.Collection.Clear();
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||||
|
using StructureHelperCommon.Services;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Cracking;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Primitives;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Primitives.Logics;
|
||||||
|
|
||||||
|
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates deep copy of crack calculator
|
||||||
|
/// </summary>
|
||||||
|
public class CrackCalculatorUpdateCloningStrategy : IUpdateStrategy<ICrackCalculator>
|
||||||
|
{
|
||||||
|
private ICloningStrategy cloningStrategy;
|
||||||
|
private IUpdateStrategy<IHasForceActions> forcesUpdateStrategy;
|
||||||
|
private IUpdateStrategy<IHasPrimitives> primitivesUpdateStrategy;
|
||||||
|
|
||||||
|
public CrackCalculatorUpdateCloningStrategy(
|
||||||
|
ICloningStrategy cloningStrategy,
|
||||||
|
IUpdateStrategy<IHasForceActions> forcesUpdateStrategy,
|
||||||
|
IUpdateStrategy<IHasPrimitives> primitivesUpdateStrategy)
|
||||||
|
{
|
||||||
|
this.cloningStrategy = cloningStrategy;
|
||||||
|
this.forcesUpdateStrategy = forcesUpdateStrategy;
|
||||||
|
this.primitivesUpdateStrategy = primitivesUpdateStrategy;
|
||||||
|
}
|
||||||
|
public CrackCalculatorUpdateCloningStrategy(ICloningStrategy cloningStrategy) : this (
|
||||||
|
cloningStrategy,
|
||||||
|
new HasForceActionUpdateCloningStrategy(cloningStrategy),
|
||||||
|
new HasPrimitivesUpdateCloningStrategy(cloningStrategy))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(ICrackCalculator targetObject, ICrackCalculator sourceObject)
|
||||||
|
{
|
||||||
|
CheckObject.IsNull(cloningStrategy);
|
||||||
|
CheckObject.IsNull(sourceObject);
|
||||||
|
CheckObject.IsNull(targetObject);
|
||||||
|
if (ReferenceEquals(targetObject, sourceObject)) { return; }
|
||||||
|
var sourceData = sourceObject.InputData;
|
||||||
|
var targetData = targetObject.InputData;
|
||||||
|
primitivesUpdateStrategy.Update(targetData, sourceData);
|
||||||
|
forcesUpdateStrategy.Update(targetData, sourceData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||||
|
using StructureHelperCommon.Services;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Primitives;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Primitives.Logics;
|
||||||
|
|
||||||
|
namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates deep copy of force calculator
|
||||||
|
/// </summary>
|
||||||
|
public class ForceCalculatorUpdateCloningStrategy : IUpdateStrategy<IForceCalculator>
|
||||||
|
{
|
||||||
|
private readonly ICloningStrategy cloningStrategy;
|
||||||
|
private readonly IUpdateStrategy<IHasForceActions> forcesUpdateStrategy;
|
||||||
|
private readonly IUpdateStrategy<IHasPrimitives> primitivesUpdateStrategy;
|
||||||
|
public ForceCalculatorUpdateCloningStrategy(ICloningStrategy cloningStrategy,
|
||||||
|
IUpdateStrategy<IHasForceActions> forcesUpdateStrategy,
|
||||||
|
IUpdateStrategy<IHasPrimitives> primitivesUpdateStrategy)
|
||||||
|
{
|
||||||
|
this.cloningStrategy = cloningStrategy;
|
||||||
|
this.forcesUpdateStrategy = forcesUpdateStrategy;
|
||||||
|
this.primitivesUpdateStrategy = primitivesUpdateStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForceCalculatorUpdateCloningStrategy(ICloningStrategy cloningStrategy) : this (
|
||||||
|
cloningStrategy,
|
||||||
|
new HasForceActionUpdateCloningStrategy(cloningStrategy),
|
||||||
|
new HasPrimitivesUpdateCloningStrategy(cloningStrategy))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(IForceCalculator targetObject, IForceCalculator sourceObject)
|
||||||
|
{
|
||||||
|
CheckObject.IsNull(cloningStrategy);
|
||||||
|
CheckObject.IsNull(sourceObject);
|
||||||
|
CheckObject.IsNull(targetObject);
|
||||||
|
if (ReferenceEquals(targetObject, sourceObject)) { return; }
|
||||||
|
var sourceData = sourceObject.InputData;
|
||||||
|
var targetData = targetObject.InputData;
|
||||||
|
primitivesUpdateStrategy.Update(targetData, sourceData);
|
||||||
|
forcesUpdateStrategy.Update(targetData, sourceData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using StructureHelperCommon.Models.Calculators;
|
|||||||
using StructureHelperCommon.Models.Parameters;
|
using StructureHelperCommon.Models.Parameters;
|
||||||
using StructureHelperCommon.Services;
|
using StructureHelperCommon.Services;
|
||||||
using StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve;
|
using StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics;
|
||||||
using StructureHelperLogics.NdmCalculations.Cracking;
|
using StructureHelperLogics.NdmCalculations.Cracking;
|
||||||
using StructureHelperLogics.NdmCalculations.Primitives;
|
using StructureHelperLogics.NdmCalculations.Primitives;
|
||||||
using StructureHelperLogics.NdmCalculations.Primitives.Logics;
|
using StructureHelperLogics.NdmCalculations.Primitives.Logics;
|
||||||
@@ -16,29 +17,29 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
|
|||||||
public class HasCalculatorsUpdateCloningStrategy : IUpdateStrategy<IHasCalculators>
|
public class HasCalculatorsUpdateCloningStrategy : IUpdateStrategy<IHasCalculators>
|
||||||
{
|
{
|
||||||
private ICloningStrategy cloningStrategy;
|
private ICloningStrategy cloningStrategy;
|
||||||
private IUpdateStrategy<IHasForceActions> forcesUpdateStrategy;
|
private IUpdateStrategy<IForceCalculator> forceCalculatorUpdateStrategy;
|
||||||
private IUpdateStrategy<IHasPrimitives> primitivesUpdateStrategy;
|
private IUpdateStrategy<ICrackCalculator> crackCalculatorUpdateStrategy;
|
||||||
private IUpdateStrategy<ILimitCurvesCalculatorInputData> limitCurvesInputDataUpdateStrategy;
|
private IUpdateStrategy<ILimitCurvesCalculator> limitCurvesCalculatorUpdateStrategy;
|
||||||
|
|
||||||
public HasCalculatorsUpdateCloningStrategy(ICloningStrategy cloningStrategy) : this(
|
public HasCalculatorsUpdateCloningStrategy(ICloningStrategy cloningStrategy) : this(
|
||||||
cloningStrategy,
|
cloningStrategy,
|
||||||
new HasForceActionUpdateCloningStrategy(cloningStrategy),
|
new ForceCalculatorUpdateCloningStrategy(cloningStrategy),
|
||||||
new HasPrimitivesUpdateCloningStrategy(cloningStrategy),
|
new CrackCalculatorUpdateCloningStrategy(cloningStrategy),
|
||||||
new LimitCurvesCalculatorInputDataUpdateStrategy()
|
new LimitCurvesCalculatorUpdateCloningStrategy(cloningStrategy)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public HasCalculatorsUpdateCloningStrategy(
|
public HasCalculatorsUpdateCloningStrategy(
|
||||||
ICloningStrategy cloningStrategy,
|
ICloningStrategy cloningStrategy,
|
||||||
IUpdateStrategy<IHasForceActions> forcesUpdateStrategy,
|
IUpdateStrategy<IForceCalculator> forceCalculatorUpdateStrategy,
|
||||||
IUpdateStrategy<IHasPrimitives> primitivesUpdateStrategy,
|
IUpdateStrategy<ICrackCalculator> crackCalculatorUpdateStrategy,
|
||||||
IUpdateStrategy<ILimitCurvesCalculatorInputData> limitCurvesInputDataUpdateStrategy)
|
IUpdateStrategy<ILimitCurvesCalculator> limitCurvesCalculatorUpdateStrategy)
|
||||||
{
|
{
|
||||||
this.cloningStrategy = cloningStrategy;
|
this.cloningStrategy = cloningStrategy;
|
||||||
this.forcesUpdateStrategy = forcesUpdateStrategy;
|
this.forceCalculatorUpdateStrategy = forceCalculatorUpdateStrategy;
|
||||||
this.primitivesUpdateStrategy = primitivesUpdateStrategy;
|
this.crackCalculatorUpdateStrategy = crackCalculatorUpdateStrategy;
|
||||||
this.limitCurvesInputDataUpdateStrategy = limitCurvesInputDataUpdateStrategy;
|
this.limitCurvesCalculatorUpdateStrategy = limitCurvesCalculatorUpdateStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(IHasCalculators targetObject, IHasCalculators sourceObject)
|
public void Update(IHasCalculators targetObject, IHasCalculators sourceObject)
|
||||||
@@ -53,15 +54,15 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
|
|||||||
var newCalculator = cloningStrategy.Clone(calculator);
|
var newCalculator = cloningStrategy.Clone(calculator);
|
||||||
if (calculator is IForceCalculator forceCalculator)
|
if (calculator is IForceCalculator forceCalculator)
|
||||||
{
|
{
|
||||||
ProcessForceCalculator(newCalculator, forceCalculator);
|
forceCalculatorUpdateStrategy.Update(newCalculator as IForceCalculator, forceCalculator);
|
||||||
}
|
}
|
||||||
else if (calculator is CrackCalculator crackCalculator)
|
else if (calculator is ICrackCalculator crackCalculator)
|
||||||
{
|
{
|
||||||
ProcessCrackCalculator(newCalculator, crackCalculator);
|
crackCalculatorUpdateStrategy.Update(newCalculator as ICrackCalculator, crackCalculator);
|
||||||
}
|
}
|
||||||
else if (calculator is ILimitCurvesCalculator limitCalculator)
|
else if (calculator is ILimitCurvesCalculator limitCalculator)
|
||||||
{
|
{
|
||||||
ProcessLimitCurvesCalculator(newCalculator, limitCalculator);
|
limitCurvesCalculatorUpdateStrategy.Update(newCalculator as ILimitCurvesCalculator, limitCalculator);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -70,45 +71,5 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces
|
|||||||
targetObject.Calculators.Add(newCalculator);
|
targetObject.Calculators.Add(newCalculator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessLimitCurvesCalculator(ICalculator newCalculator, ILimitCurvesCalculator limitCalculator)
|
|
||||||
{
|
|
||||||
var sourceData = limitCalculator.InputData;
|
|
||||||
var targetData = ((ILimitCurvesCalculator)newCalculator).InputData;
|
|
||||||
limitCurvesInputDataUpdateStrategy.Update(targetData, sourceData);
|
|
||||||
foreach (var series in targetData.PrimitiveSeries)
|
|
||||||
{
|
|
||||||
List<INdmPrimitive> collection = UpdatePrimitivesCollection(series);
|
|
||||||
series.Collection.AddRange(collection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessCrackCalculator(ICalculator newCalculator, CrackCalculator crackCalculator)
|
|
||||||
{
|
|
||||||
var sourceData = crackCalculator.InputData;
|
|
||||||
var targetData = ((ICrackCalculator)newCalculator).InputData;
|
|
||||||
primitivesUpdateStrategy.Update(targetData, sourceData);
|
|
||||||
forcesUpdateStrategy.Update(targetData, sourceData);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessForceCalculator(ICalculator newCalculator, IForceCalculator forceCalculator)
|
|
||||||
{
|
|
||||||
var sourceData = forceCalculator.InputData;
|
|
||||||
var targetData = ((IForceCalculator)newCalculator).InputData;
|
|
||||||
primitivesUpdateStrategy.Update(targetData, sourceData);
|
|
||||||
forcesUpdateStrategy.Update(targetData, sourceData);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<INdmPrimitive> UpdatePrimitivesCollection(NamedCollection<INdmPrimitive> series)
|
|
||||||
{
|
|
||||||
List<INdmPrimitive> collection = new();
|
|
||||||
foreach (var item in series.Collection)
|
|
||||||
{
|
|
||||||
var newItem = cloningStrategy.Clone(item);
|
|
||||||
collection.Add(newItem);
|
|
||||||
}
|
|
||||||
series.Collection.Clear();
|
|
||||||
return collection;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||||
|
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Cracking;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Primitives;
|
||||||
|
|
||||||
|
namespace StructureHelperTests.UnitTests.UpdateStrategiesTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class CrackCalculatorUpdateCloningStrategyTests
|
||||||
|
{
|
||||||
|
private Mock<ICloningStrategy> _cloningStrategyMock;
|
||||||
|
private Mock<IUpdateStrategy<IHasForceActions>> _forcesUpdateStrategyMock;
|
||||||
|
private Mock<IUpdateStrategy<IHasPrimitives>> _primitivesUpdateStrategyMock;
|
||||||
|
private CrackCalculatorUpdateCloningStrategy _strategy;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
_cloningStrategyMock = new Mock<ICloningStrategy>();
|
||||||
|
_forcesUpdateStrategyMock = new Mock<IUpdateStrategy<IHasForceActions>>();
|
||||||
|
_primitivesUpdateStrategyMock = new Mock<IUpdateStrategy<IHasPrimitives>>();
|
||||||
|
|
||||||
|
_strategy = new CrackCalculatorUpdateCloningStrategy(
|
||||||
|
_cloningStrategyMock.Object,
|
||||||
|
_forcesUpdateStrategyMock.Object,
|
||||||
|
_primitivesUpdateStrategyMock.Object
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithNullSourceObject_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var targetObject = Mock.Of<ICrackCalculator>();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<StructureHelperException>(() => _strategy.Update(targetObject, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithNullTargetObject_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sourceObject = Mock.Of<ICrackCalculator>();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<StructureHelperException>(() => _strategy.Update(null, sourceObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithSameSourceAndTarget_DoesNothing()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sourceObject = Mock.Of<ICrackCalculator>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_strategy.Update(sourceObject, sourceObject);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_forcesUpdateStrategyMock.VerifyNoOtherCalls();
|
||||||
|
_primitivesUpdateStrategyMock.VerifyNoOtherCalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_InvokesUpdateStrategiesOnInputData()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sourceDataMock = new Mock<ICrackCalculatorInputData>();
|
||||||
|
var targetDataMock = new Mock<ICrackCalculatorInputData>();
|
||||||
|
|
||||||
|
var sourceObjectMock = new Mock<ICrackCalculator>();
|
||||||
|
sourceObjectMock.Setup(s => s.InputData).Returns(sourceDataMock.Object);
|
||||||
|
|
||||||
|
var targetObjectMock = new Mock<ICrackCalculator>();
|
||||||
|
targetObjectMock.Setup(t => t.InputData).Returns(targetDataMock.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_strategy.Update(targetObjectMock.Object, sourceObjectMock.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_primitivesUpdateStrategyMock.Verify(ps => ps.Update(targetDataMock.Object, sourceDataMock.Object), Times.Once);
|
||||||
|
_forcesUpdateStrategyMock.Verify(fs => fs.Update(targetDataMock.Object, sourceDataMock.Object), Times.Once);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||||
|
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||||
|
|
||||||
|
namespace StructureHelperTests.UnitTests.UpdateStrategiesTests
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class DeepCloningStrategyTests
|
||||||
|
{
|
||||||
|
private DeepCloningStrategy _strategy;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
_strategy = new DeepCloningStrategy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Clone_WithNullOriginal_ReturnsNull()
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var result = _strategy.Clone<object>(null);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsNull(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Clone_WhenObjectAlreadyCloned_ReturnsExistingClone()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var original = new Mock<ICloneable>().Object;
|
||||||
|
var expectedClone = new Mock<ICloneable>().Object;
|
||||||
|
|
||||||
|
// Use reflection to populate the internal dictionary (_clonedObjects)
|
||||||
|
var clonedObjects = new Dictionary<object, object> { { original, expectedClone } };
|
||||||
|
var internalField = typeof(DeepCloningStrategy).GetField("_clonedObjects", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
internalField.SetValue(_strategy, clonedObjects);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _strategy.Clone(original);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreSame(expectedClone, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Clone_WithCustomCloneStrategy_UsesCloneStrategyToCloneObject()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var original = new Mock<ICloneable>().Object;
|
||||||
|
var expectedClone = new Mock<ICloneable>().Object;
|
||||||
|
|
||||||
|
var cloneStrategyMock = new Mock<ICloneStrategy<ICloneable>>();
|
||||||
|
cloneStrategyMock.Setup(cs => cs.GetClone(original)).Returns(expectedClone);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _strategy.Clone(original, cloneStrategyMock.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreSame(expectedClone, result);
|
||||||
|
cloneStrategyMock.Verify(cs => cs.GetClone(original), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Clone_WhenObjectImplementsICloneable_UsesCloneMethod()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var originalMock = new Mock<ICloneable>();
|
||||||
|
var expectedClone = new Mock<ICloneable>().Object;
|
||||||
|
|
||||||
|
originalMock.Setup(o => o.Clone()).Returns(expectedClone);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _strategy.Clone(originalMock.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreSame(expectedClone, result);
|
||||||
|
originalMock.Verify(o => o.Clone(), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Clone_WhenObjectNotCloneableAndNoCloneStrategy_ThrowsStructureHelperException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var original = new object(); // Not ICloneable
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var exception = Assert.Throws<StructureHelperException>(() => _strategy.Clone(original));
|
||||||
|
Assert.That(exception.Message, Does.Contain("object is not IClonable and cloning strategy is null"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Clone_AddsClonedObjectToDictionary()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var originalMock = new Mock<ICloneable>();
|
||||||
|
var expectedClone = new Mock<ICloneable>().Object;
|
||||||
|
|
||||||
|
originalMock.Setup(o => o.Clone()).Returns(expectedClone);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = _strategy.Clone(originalMock.Object);
|
||||||
|
|
||||||
|
// Use reflection to check the private dictionary (_clonedObjects)
|
||||||
|
var internalField = typeof(DeepCloningStrategy).GetField("_clonedObjects", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
var clonedObjects = (Dictionary<object, object>)internalField.GetValue(_strategy);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreSame(expectedClone, clonedObjects[originalMock.Object]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||||
|
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Analyses.ByForces;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Primitives;
|
||||||
|
|
||||||
|
namespace StructureHelperTests.UnitTests.UpdateStrategiesTests
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class ForceCalculatorUpdateCloningStrategyTests
|
||||||
|
{
|
||||||
|
private Mock<ICloningStrategy> _cloningStrategyMock;
|
||||||
|
private Mock<IUpdateStrategy<IHasForceActions>> _forcesUpdateStrategyMock;
|
||||||
|
private Mock<IUpdateStrategy<IHasPrimitives>> _primitivesUpdateStrategyMock;
|
||||||
|
private ForceCalculatorUpdateCloningStrategy _strategy;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
_cloningStrategyMock = new Mock<ICloningStrategy>();
|
||||||
|
_forcesUpdateStrategyMock = new Mock<IUpdateStrategy<IHasForceActions>>();
|
||||||
|
_primitivesUpdateStrategyMock = new Mock<IUpdateStrategy<IHasPrimitives>>();
|
||||||
|
|
||||||
|
_strategy = new ForceCalculatorUpdateCloningStrategy(
|
||||||
|
_cloningStrategyMock.Object,
|
||||||
|
_forcesUpdateStrategyMock.Object,
|
||||||
|
_primitivesUpdateStrategyMock.Object
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithNullSourceObject_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var targetObject = Mock.Of<IForceCalculator>();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<StructureHelperException>(() => _strategy.Update(targetObject, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithNullTargetObject_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sourceObject = Mock.Of<IForceCalculator>();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<StructureHelperException>(() => _strategy.Update(null, sourceObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithSameSourceAndTarget_DoesNothing()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sourceObject = Mock.Of<IForceCalculator>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_strategy.Update(sourceObject, sourceObject);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_forcesUpdateStrategyMock.VerifyNoOtherCalls();
|
||||||
|
_primitivesUpdateStrategyMock.VerifyNoOtherCalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_InvokesUpdateStrategiesOnInputData()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sourceDataMock = new Mock<IForceCalculatorInputData>();
|
||||||
|
var targetDataMock = new Mock<IForceCalculatorInputData>();
|
||||||
|
|
||||||
|
var sourceObjectMock = new Mock<IForceCalculator>();
|
||||||
|
sourceObjectMock.Setup(s => s.InputData).Returns(sourceDataMock.Object);
|
||||||
|
|
||||||
|
var targetObjectMock = new Mock<IForceCalculator>();
|
||||||
|
targetObjectMock.Setup(t => t.InputData).Returns(targetDataMock.Object);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_strategy.Update(targetObjectMock.Object, sourceObjectMock.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_primitivesUpdateStrategyMock.Verify(ps => ps.Update(targetDataMock.Object, sourceDataMock.Object), Times.Once);
|
||||||
|
_forcesUpdateStrategyMock.Verify(fs => fs.Update(targetDataMock.Object, sourceDataMock.Object), Times.Once);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||||
|
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||||
|
using StructureHelperCommon.Models.Calculators;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Analyses.ByForces;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Cracking;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace StructureHelperTests.UnitTests.UpdateStrategiesTests
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class HasCalculatorsUpdateCloningStrategyTests
|
||||||
|
{
|
||||||
|
private Mock<ICloningStrategy> _cloningStrategyMock;
|
||||||
|
private Mock<IUpdateStrategy<IForceCalculator>> _forceCalculatorUpdateStrategyMock;
|
||||||
|
private Mock<IUpdateStrategy<ICrackCalculator>> _crackCalculatorUpdateStrategyMock;
|
||||||
|
private Mock<IUpdateStrategy<ILimitCurvesCalculator>> _limitCurvesCalculatorUpdateStrategyMock;
|
||||||
|
private HasCalculatorsUpdateCloningStrategy _strategy;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
_cloningStrategyMock = new Mock<ICloningStrategy>();
|
||||||
|
_forceCalculatorUpdateStrategyMock = new Mock<IUpdateStrategy<IForceCalculator>>();
|
||||||
|
_crackCalculatorUpdateStrategyMock = new Mock<IUpdateStrategy<ICrackCalculator>>();
|
||||||
|
_limitCurvesCalculatorUpdateStrategyMock = new Mock<IUpdateStrategy<ILimitCurvesCalculator>>();
|
||||||
|
|
||||||
|
_strategy = new HasCalculatorsUpdateCloningStrategy(
|
||||||
|
_cloningStrategyMock.Object,
|
||||||
|
_forceCalculatorUpdateStrategyMock.Object,
|
||||||
|
_crackCalculatorUpdateStrategyMock.Object,
|
||||||
|
_limitCurvesCalculatorUpdateStrategyMock.Object
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithNullSourceObject_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var targetObject = Mock.Of<IHasCalculators>();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<StructureHelperException>(() => _strategy.Update(targetObject, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithNullTargetObject_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sourceObject = Mock.Of<IHasCalculators>();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<StructureHelperException>(() => _strategy.Update(null, sourceObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithSameSourceAndTarget_DoesNothing()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var calculators = new List<ICalculator> { Mock.Of<IForceCalculator>() };
|
||||||
|
var sourceObject = Mock.Of<IHasCalculators>(s => s.Calculators == calculators);
|
||||||
|
var targetObject = sourceObject;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_strategy.Update(targetObject, sourceObject);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_cloningStrategyMock.VerifyNoOtherCalls();
|
||||||
|
_forceCalculatorUpdateStrategyMock.VerifyNoOtherCalls();
|
||||||
|
_crackCalculatorUpdateStrategyMock.VerifyNoOtherCalls();
|
||||||
|
_limitCurvesCalculatorUpdateStrategyMock.VerifyNoOtherCalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_ProcessesEachCalculatorCorrectly()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sourceForceCalculator = Mock.Of<IForceCalculator>(x => x.Name == "Force");
|
||||||
|
var sourceCrackCalculator = Mock.Of<ICrackCalculator>(x => x.Name == "Crack");
|
||||||
|
var sourceLimitCurvesCalculator = Mock.Of<ILimitCurvesCalculator>(x => x.Name == "Curves");
|
||||||
|
var sourceCalculators = new List<ICalculator>
|
||||||
|
{
|
||||||
|
sourceForceCalculator,
|
||||||
|
sourceCrackCalculator,
|
||||||
|
sourceLimitCurvesCalculator
|
||||||
|
};
|
||||||
|
var sourceObjectMock = new Mock<IHasCalculators>();
|
||||||
|
sourceObjectMock.Setup(s => s.Calculators).Returns(sourceCalculators);
|
||||||
|
|
||||||
|
var targetCalculators = new List<ICalculator>();
|
||||||
|
var targetObjectMock = new Mock<IHasCalculators>();
|
||||||
|
targetObjectMock.Setup(t => t.Calculators).Returns(targetCalculators);
|
||||||
|
|
||||||
|
var clonedForceCalculator = Mock.Of<IForceCalculator>();
|
||||||
|
var clonedCrackCalculator = Mock.Of<ICrackCalculator>();
|
||||||
|
var clonedLimitCurvesCalculator = Mock.Of<ILimitCurvesCalculator>();
|
||||||
|
|
||||||
|
_cloningStrategyMock.Setup(cs => cs.Clone(It.Is<ICalculator>(x => x.Name == "Force"), null)).Returns(clonedForceCalculator);
|
||||||
|
_cloningStrategyMock.Setup(cs => cs.Clone(It.Is<ICalculator>(x => x.Name == "Crack"), null)).Returns(clonedCrackCalculator);
|
||||||
|
_cloningStrategyMock.Setup(cs => cs.Clone(It.Is<ICalculator>(x => x.Name == "Curves"), null)).Returns(clonedLimitCurvesCalculator);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_strategy.Update(targetObjectMock.Object, sourceObjectMock.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.That(targetCalculators, Has.Count.EqualTo(3));
|
||||||
|
Assert.That(targetCalculators, Contains.Item(clonedForceCalculator));
|
||||||
|
Assert.That(targetCalculators, Contains.Item(clonedCrackCalculator));
|
||||||
|
Assert.That(targetCalculators, Contains.Item(clonedLimitCurvesCalculator));
|
||||||
|
|
||||||
|
_forceCalculatorUpdateStrategyMock.Verify(f => f.Update(clonedForceCalculator, sourceForceCalculator), Times.Once);
|
||||||
|
_crackCalculatorUpdateStrategyMock.Verify(c => c.Update(clonedCrackCalculator, sourceCrackCalculator), Times.Once);
|
||||||
|
_limitCurvesCalculatorUpdateStrategyMock.Verify(l => l.Update(clonedLimitCurvesCalculator, sourceLimitCurvesCalculator), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithUnknownCalculatorType_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var unknownCalculator = Mock.Of<ICalculator>();
|
||||||
|
var sourceCalculators = new List<ICalculator> { unknownCalculator };
|
||||||
|
var sourceObjectMock = new Mock<IHasCalculators>();
|
||||||
|
sourceObjectMock.Setup(s => s.Calculators).Returns(sourceCalculators);
|
||||||
|
|
||||||
|
var targetObjectMock = new Mock<IHasCalculators>();
|
||||||
|
targetObjectMock.Setup(t => t.Calculators).Returns(new List<ICalculator>());
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var exception = Assert.Throws<StructureHelperException>(() => _strategy.Update(targetObjectMock.Object, sourceObjectMock.Object));
|
||||||
|
Assert.That(exception.Message, Does.Contain(ErrorStrings.ObjectTypeIsUnknown));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||||
|
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||||
|
using StructureHelperCommon.Models.Parameters;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Analyses.ByForces;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Analyses.ByForces.LimitCurve;
|
||||||
|
using StructureHelperLogics.NdmCalculations.Primitives;
|
||||||
|
|
||||||
|
namespace StructureHelperTests.UnitTests.UpdateStrategiesTests
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class LimitCurvesCalculatorUpdateCloningStrategyTests
|
||||||
|
{
|
||||||
|
private Mock<ICloningStrategy> _cloningStrategyMock;
|
||||||
|
private Mock<IUpdateStrategy<ILimitCurvesCalculatorInputData>> _inputDataUpdateStrategyMock;
|
||||||
|
private LimitCurvesCalculatorUpdateCloningStrategy _strategy;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
_cloningStrategyMock = new Mock<ICloningStrategy>();
|
||||||
|
_inputDataUpdateStrategyMock = new Mock<IUpdateStrategy<ILimitCurvesCalculatorInputData>>();
|
||||||
|
_strategy = new LimitCurvesCalculatorUpdateCloningStrategy(
|
||||||
|
_cloningStrategyMock.Object,
|
||||||
|
_inputDataUpdateStrategyMock.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithNullSourceObject_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var targetObject = Mock.Of<ILimitCurvesCalculator>();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<StructureHelperException>(() => _strategy.Update(targetObject, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithNullTargetObject_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sourceObject = Mock.Of<ILimitCurvesCalculator>();
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
Assert.Throws<StructureHelperException>(() => _strategy.Update(null, sourceObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Update_WithSameSourceAndTarget_DoesNothing()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sourceObject = Mock.Of<ILimitCurvesCalculator>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_strategy.Update(sourceObject, sourceObject);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_cloningStrategyMock.VerifyNoOtherCalls();
|
||||||
|
_inputDataUpdateStrategyMock.VerifyNoOtherCalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
//[Test]
|
||||||
|
public void Update_UpdatesInputDataAndProcessesEachPrimitiveSeries()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var targetSeries = new NamedCollection<INdmPrimitive> { Collection = new List<INdmPrimitive>() };
|
||||||
|
var targetData = Mock.Of<ILimitCurvesCalculatorInputData>(d => d.PrimitiveSeries == new List<NamedCollection<INdmPrimitive>> { targetSeries });
|
||||||
|
|
||||||
|
var targetObjectMock = new Mock<ILimitCurvesCalculator>();
|
||||||
|
targetObjectMock.Setup(t => t.InputData).Returns(targetData);
|
||||||
|
|
||||||
|
var sourcePrimitive1 = Mock.Of<INdmPrimitive>(p => p.Name == "sp1");
|
||||||
|
var sourcePrimitive2 = Mock.Of<INdmPrimitive>(p => p.Name == "sp2");
|
||||||
|
var sourceSeries = new NamedCollection<INdmPrimitive>
|
||||||
|
{
|
||||||
|
Collection = new List<INdmPrimitive> { sourcePrimitive1, sourcePrimitive2 }
|
||||||
|
};
|
||||||
|
var sourceData = Mock.Of<ILimitCurvesCalculatorInputData>(d => d.PrimitiveSeries == new List<NamedCollection<INdmPrimitive>> { sourceSeries });
|
||||||
|
|
||||||
|
var sourceObjectMock = new Mock<ILimitCurvesCalculator>();
|
||||||
|
sourceObjectMock.Setup(s => s.InputData).Returns(sourceData);
|
||||||
|
|
||||||
|
var clonedPrimitive1 = Mock.Of<INdmPrimitive>(p => p.Name == "cp1");
|
||||||
|
var clonedPrimitive2 = Mock.Of<INdmPrimitive>(p => p.Name == "cp2");
|
||||||
|
|
||||||
|
_cloningStrategyMock.Setup(cs => cs.Clone(It.Is<INdmPrimitive>(p => p.Name == "sp1"), null)).Returns(clonedPrimitive1);
|
||||||
|
_cloningStrategyMock.Setup(cs => cs.Clone(It.Is<INdmPrimitive>(p => p.Name == "sp2"), null)).Returns(clonedPrimitive2);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_strategy.Update(targetObjectMock.Object, sourceObjectMock.Object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_inputDataUpdateStrategyMock.Verify(
|
||||||
|
us => us.Update(targetData, sourceData),
|
||||||
|
Times.Once);
|
||||||
|
|
||||||
|
Assert.That(targetSeries.Collection, Has.Count.EqualTo(2));
|
||||||
|
Assert.That(targetSeries.Collection, Contains.Item(clonedPrimitive1));
|
||||||
|
Assert.That(targetSeries.Collection, Contains.Item(clonedPrimitive2));
|
||||||
|
|
||||||
|
_cloningStrategyMock.Verify(cs => cs.Clone(sourcePrimitive1, null), Times.Once);
|
||||||
|
_cloningStrategyMock.Verify(cs => cs.Clone(sourcePrimitive2, null), Times.Once);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user