Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Base_Engine: add method to unpack IContainers #3001

Merged
merged 22 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .ci/unit-tests/BHoM_Engine_Tests.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.32126.317
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BHoM_Engine", "..\..\BHoM_Engine\BHoM_Engine.csproj", "{978825AF-5522-4974-840A-72FC7192D1FB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Base_Engine_Tests", "Base_Engine_Tests\Base_Engine_Tests.csproj", "{7BC6FDD9-D978-4308-A021-EDE953748AB7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Test|Any CPU = Test|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{978825AF-5522-4974-840A-72FC7192D1FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{978825AF-5522-4974-840A-72FC7192D1FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{978825AF-5522-4974-840A-72FC7192D1FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{978825AF-5522-4974-840A-72FC7192D1FB}.Release|Any CPU.Build.0 = Release|Any CPU
{978825AF-5522-4974-840A-72FC7192D1FB}.Test|Any CPU.ActiveCfg = Debug|Any CPU
{978825AF-5522-4974-840A-72FC7192D1FB}.Test|Any CPU.Build.0 = Debug|Any CPU
{7BC6FDD9-D978-4308-A021-EDE953748AB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7BC6FDD9-D978-4308-A021-EDE953748AB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7BC6FDD9-D978-4308-A021-EDE953748AB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7BC6FDD9-D978-4308-A021-EDE953748AB7}.Release|Any CPU.Build.0 = Release|Any CPU
{7BC6FDD9-D978-4308-A021-EDE953748AB7}.Test|Any CPU.ActiveCfg = Test|Any CPU
{7BC6FDD9-D978-4308-A021-EDE953748AB7}.Test|Any CPU.Build.0 = Test|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB913D3B-3FD1-489E-BDF7-F8408A2DD120}
EndGlobalSection
EndGlobal
43 changes: 43 additions & 0 deletions .ci/unit-tests/Base_Engine_Tests/Base_Engine_Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>

<Configurations>Debug;Release;Test</Configurations>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoBogus" Version="2.13.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
<PackageReference Include="Shouldly" Version="4.1.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\BHoM_Engine\BHoM_Engine.csproj" />
</ItemGroup>

<ItemGroup>
<Reference Include="BHoM">
<HintPath>C:\ProgramData\BHoM\Assemblies\BHoM.dll</HintPath>
</Reference>
<Reference Include="Geometry_oM">
<HintPath>C:\ProgramData\BHoM\Assemblies\Geometry_oM.dll</HintPath>
</Reference>
<Reference Include="Structure_oM">
<HintPath>C:\ProgramData\BHoM\Assemblies\Structure_oM.dll</HintPath>
</Reference>
</ItemGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)$(TargetFileName)&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)*Bogus.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)System.Data.DataSetExtensions.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)Microsoft.VisualStudio.*.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)Microsoft.TestPlatform.*.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)testhost.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)NuGet.Frameworks.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)System.Reflection.Metadata.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)Newtonsoft.Json.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)nunit.framework.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)DiffEngine.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)System.Management.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)EmptyFiles.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; xcopy &quot;$(TargetDir)Shouldly.dll&quot; &quot;$(ProgramData)\BHoM\Assemblies&quot; /Y" />
</Target>

</Project>
60 changes: 60 additions & 0 deletions .ci/unit-tests/Base_Engine_Tests/Query/Objects/Container.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Base;
using BH.Engine.Base;
using System.Collections;

namespace BH.Tests.Engine.Base.Query.Objects
{
// Must be unpackable
public class Container<T> : BHoMObject, IContainer
{
public T? SomeObject { get; set; }
public IEnumerable<T> ListOfObjects { get; set; } = new List<T>();
public IEnumerable<IEnumerable<T>> ListOfLists { get; set; } = new List<List<T>>();
}

// We want to support this, it should get the values of the dictionary.
public class DictionaryContainer<T> : Container<T>
{
public Dictionary<string, T> Dictionary { get; set; } = new Dictionary<string, T>();
}

// We want to support this, it should get the values of the dictionary and flatten them.
public class DictionaryListContainer<T> : Container<T>
{
public Dictionary<string, IEnumerable<T>> DictionaryOfLists { get; set; } = new Dictionary<string, IEnumerable<T>>();
}

// Not supported.
public class ListOfDictionariesContainer<T> : Container<T>
{
public IEnumerable<Dictionary<string, T>> ListOfDictionaries { get; set; } = new List<Dictionary<string, T>>();
}

// Not supported.
public class ListOfListOfListContainer<T> : Container<T>
{
public IEnumerable<IEnumerable<IEnumerable<T>>> ListOfListOfLists { get; set; } = new List<List<List<T>>>();
}
}
33 changes: 33 additions & 0 deletions .ci/unit-tests/Base_Engine_Tests/Query/Objects/TestFragment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Base;
using BH.Engine.Base;
using System.Collections;

namespace BH.Tests.Engine.Base.Query.Objects
{
public class TestFragment : IFragment
{
public object? SomeObject { get; set; }
}
}
135 changes: 135 additions & 0 deletions .ci/unit-tests/Base_Engine_Tests/Query/Unpack.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Base;
using BH.Engine.Base;
using BH.Tests.Engine.Base.Query.Objects;
using NUnit.Framework;
using AutoBogus;
using Shouldly;

namespace BH.Tests.Engine.Base.Query
{
public class UnpackTests
{
/// <summary>
/// The static constructor is called only once at the test class initialisation, before everything else.
/// Some 'OneTimeSetup' configurations have to be done here, e.g. those dealing with Attributes like `TestCaseSource`.
/// </summary>
static UnpackTests()
{
// BH.Engine.Base.Create.RandomObject() cannot deal with generics and cannot fix the number of items in generated collections.
// Using AutoFaker instead.

// Configures the number of items in any collection generated by AutoFaker.
AutoFaker.Configure(builder =>
{
builder.WithRepeatCount(1);
});
}

[TearDown]
public void TearDown()
{
var events = BH.Engine.Base.Query.CurrentEvents();
if (events.Any())
{
foreach (var ev in events)
{
if (ev.Type == oM.Base.Debugging.EventType.Warning || ev.Type == oM.Base.Debugging.EventType.Error)
Assert.Warn($"{ev.Type}: {ev.Message}");
else
TestContext.Out.Write($"{ev.Type}: {ev.Message}");
}
}

BH.Engine.Base.Compute.ClearCurrentEvents();
}

private static IEnumerable<TestCaseData> GetTestContainers()
{
// The verification is done against the number of unpacked objects expected, which can be determined once AutoFaker's `WithRepeatCount` is configured.
// Example:
// AutoFaker creates 1 objects of the requested type per each IEnumerable property.
// It follows that Container<Bar> will have 1 + 1 + 1 = 3 Bars.
yield return new TestCaseData(new AutoFaker<Container<BHoMObject>>().Generate(), 3);
yield return new TestCaseData(new AutoFaker<DictionaryContainer<BHoMObject>>().Generate(), 4);
yield return new TestCaseData(new AutoFaker<DictionaryListContainer<BHoMObject>>().Generate(), 4);
yield return new TestCaseData(new AutoFaker<ListOfDictionariesContainer<BHoMObject>>().Generate(), 3);
yield return new TestCaseData(new AutoFaker<ListOfListOfListContainer<BHoMObject>>().Generate(), 3);
}

private static IEnumerable<TestCaseData> GetTestContainerOfContainers()
{
// Container of containers.
// The verification is done against the number of unpacked objects expected, which can be determined once AutoFaker's `WithRepeatCount` is configured.
// Example:
// AutoFaker creates 1 objects of the requested type per each IEnumerable property.
// It follows that Container<Container<Bar>> will have 3 + 3 + 3 = 9 Bars.
yield return new TestCaseData(new AutoFaker<Container<Container<BHoMObject>>>().Generate(), 9);
yield return new TestCaseData(new AutoFaker<DictionaryContainer<Container<BHoMObject>>>().Generate(), 12);
yield return new TestCaseData(new AutoFaker<DictionaryListContainer<Container<BHoMObject>>>().Generate(), 12);
yield return new TestCaseData(new AutoFaker<ListOfDictionariesContainer<Container<BHoMObject>>>().Generate(), 9);
yield return new TestCaseData(new AutoFaker<ListOfListOfListContainer<Container<BHoMObject>>>().Generate(), 9);
}

[Test]
[TestCaseSource(nameof(GetTestContainers))]
public void Unpack<T>(Container<T> container, int numberOfObjects)
{
var result = container.Unpack();

result.OfType<T>().Count().ShouldBeEquivalentTo(numberOfObjects);
}

[Test]
[TestCaseSource(nameof(GetTestContainerOfContainers))]
public void UnpackContainerOfContainers<T>(Container<T> container, int numberOfObjects)
{
var result = container.Unpack();

result.OfType<BHoMObject>().Count().ShouldBeEquivalentTo(numberOfObjects);
}

[Test]
public void Unpack_DisregardCustomData()
{
var validContainer = new AutoFaker<Container<BHoMObject>>().Generate();
validContainer.CustomData["bar"] = new AutoFaker<BHoMObject>().Generate();

var result = validContainer.Unpack();

result.OfType<BHoMObject>().Count().ShouldBeEquivalentTo(3);
}

[Test]
public void Unpack_DisregardFragments()
{
var validContainer = new AutoFaker<Container<BHoMObject>>().Generate();
validContainer.Fragments.Add(new TestFragment() { SomeObject = new BHoMObject() });

var result = validContainer.Unpack();

result.OfType<BHoMObject>().Count().ShouldBeEquivalentTo(3);
}
}
}
3 changes: 2 additions & 1 deletion BHoM_Engine/BHoM_Engine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
<Copyright>Copyright © https://github.com/BHoM</Copyright>
<RootNamespace>BH.Engine.Base</RootNamespace>
<FileVersion>6.1.0.0</FileVersion>
<Configurations>Debug;Release;Test</Configurations>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\Build\</OutputPath>
</PropertyGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy &quot;$(TargetDir)$(TargetFileName)&quot; &quot;C:\ProgramData\BHoM\Assemblies&quot; /Y&#xD;&#xA;xcopy &quot;$(TargetDir)DeepCloner.dll&quot; &quot;C:\ProgramData\BHoM\Assemblies&quot; /Y" />
<Exec Command="if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; (xcopy &quot;$(TargetDir)$(TargetFileName)&quot; &quot;C:\ProgramData\BHoM\Assemblies&quot; /Y)&#xD;&#xA;if not &quot;$(ConfigurationName)&quot; == &quot;Test&quot; (xcopy &quot;$(TargetDir)DeepCloner.dll&quot; &quot;C:\ProgramData\BHoM\Assemblies&quot; /Y)" />
</Target>

<ItemGroup>
Expand Down
Loading