Skip to content
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: 27 additions & 9 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,44 @@ jobs:
with:
fetch-depth: 0

- name: Setup .NET 9 SDK
- name: Setup .NET 10 SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x
dotnet-version: 10.0.x
cache: true
cache-dependency-path: |
**/*.sln
**/*.slnx
**/*.csproj

- name: Restore
run: dotnet restore
- name: Restore (each csproj)
shell: pwsh
run: |
$projects = Get-ChildItem -Recurse -Filter *.csproj -File
if (-not $projects) { Write-Host "No csproj files found"; exit 1 }
foreach ($p in $projects) {
echo "Restoring $($p.FullName)"
dotnet restore --nologo "$($p.FullName)"
}

- name: Build
run: dotnet build --configuration Release --no-restore /p:ContinuousIntegrationBuild=true
- name: Build (Release)
shell: pwsh
run: |
$projects = Get-ChildItem -Recurse -Filter *.csproj -File | ForEach-Object { $_.FullName }
foreach ($p in $projects) {
echo "Building $p"
dotnet build "$p" --configuration Release --no-restore /p:ContinuousIntegrationBuild=true
}

- name: Test
if: ${{ hashFiles('**/*Tests.csproj') != '' || hashFiles('**/*Test.csproj') != '' }}
run: >-
dotnet test --configuration Release --no-build --verbosity normal
--collect:"XPlat Code Coverage" --logger "trx;LogFileName=test_results.trx"
shell: pwsh
run: |
$testProjects = Get-ChildItem -Recurse -Include *Tests.csproj,*Test.csproj -File | ForEach-Object { $_.FullName }
foreach ($tp in $testProjects) {
echo "Testing $tp"
dotnet test "$tp" --configuration Release --no-build --verbosity normal --collect:"XPlat Code Coverage" --logger "trx;LogFileName=test_results.trx"
}

- name: Upload test results
if: ${{ always() && (hashFiles('**/*Tests.csproj') != '' || hashFiles('**/*Test.csproj') != '' ) }}
Expand Down
22 changes: 18 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Setup .NET 9 SDK
- name: Setup .NET 10 SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x
dotnet-version: 10.0.x
cache: true
cache-dependency-path: |
**/*.sln
**/*.slnx
**/*.csproj

- name: Initialize CodeQL
uses: github/codeql-action/init@v3
Expand All @@ -44,9 +49,18 @@ jobs:

- name: Manual build fallback
if: failure()
shell: pwsh
run: |
dotnet restore
dotnet build --configuration Release --no-restore
$projects = Get-ChildItem -Recurse -Filter *.csproj -File
if (-not $projects) { Write-Host "No csproj files found"; exit 1 }
foreach ($p in $projects) {
echo "Restoring $($p.FullName)"
dotnet restore --nologo "$($p.FullName)"
}
foreach ($p in $projects) {
echo "Building $($p.FullName)"
dotnet build "$($p.FullName)" --configuration Release --no-restore /p:ContinuousIntegrationBuild=true
}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
Expand Down
2 changes: 1 addition & 1 deletion Services/Layering/StripFillGenerationStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public List<Layer> Generate(List<SKU> skus, SupportSurface supportSurface, Gener

double util = usedArea / area;
string desc = $"rows={nrows} seq=" + string.Join(",", seq.Select(v => $"{v.sref.Name}:{v.w}x{v.h}"));
string lid = $"strip_r{nrows}_" + string.Join("_", seq.Select(v => $"{v.sref.Name.Replace(' ', '_')}{v.w}x{v.h}"));
string lid = $"strip_r{nrows}";

int layerHeight = seq.Count != 0 ? seq.Max(v => v.sref.Height) : 0;
var metadata = new LayerMetadata(util, layerHeight, desc);
Expand Down
18 changes: 11 additions & 7 deletions Stack-Solver.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows10.0.26100.1</TargetFramework>
<TargetFramework>net10.0-windows</TargetFramework>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ApplicationIcon>Box.ico</ApplicationIcon>
<UseWPF>true</UseWPF>
Expand All @@ -17,6 +17,10 @@
<EmbeddedResource Remove="Controls\**" />
<None Remove="Controls\**" />
<Page Remove="Controls\**" />
<Compile Remove="Tests\**" />
<EmbeddedResource Remove="Tests\**" />
<None Remove="Tests\**" />
<Page Remove="Tests\**" />
</ItemGroup>

<ItemGroup>
Expand All @@ -25,16 +29,16 @@

<ItemGroup>
<PackageReference Include="Google.OrTools" Version="9.14.6206" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="9.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.9">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="10.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="WPF-UI" Version="4.0.3" />
<PackageReference Include="WPF-UI.DependencyInjection" Version="4.0.3" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0 " />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion Stack-Solver.slnx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Solution>
<Project Path="../Stack-Solver-Tests/Stack-Solver-Tests.csproj" Id="39597fc4-81df-463b-8581-9fa36df424e3" />
<Project Path="Stack-Solver.csproj" />
<Project Path="Tests/Stack-Solver.Tests/Stack-Solver.Tests.csproj" Id="f381e69c-0b5f-4653-856f-a6e51e51e45b" />
</Solution>
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using Stack_Solver.Models;
using Stack_Solver.Models.Supports;
using Stack_Solver.Services.Layering;
using Xunit;


namespace Stack_Solver.Tests.Strategies
{
public class BLFGenerationStrategyTests
{
[Fact]
public void Generate_SingleSKU()
{
var skus = new List<SKU>
{
new() {
SkuId = "A",
Name = "Box A",
Length = 50,
Width = 30,
Height = 20,
Quantity = 500,
Rotatable = true
}
};

var pallet = new Pallet("Standard Pallet", 800, 60, 14);

var strategy = new BLFGenerationStrategy();
var options = new GenerationOptions { };

var layers = strategy.Generate(skus, pallet, options);

Assert.NotEmpty(layers);
layers.Sort((l1, l2) => l1.Items.Count.CompareTo(l2.Items.Count));
Assert.Equal(32, layers.Last().Items.Count);
}

[Fact]
public void Generate_MultipleSKUs()
{
var skus = new List<SKU>
{
new() {
SkuId = "A",
Name = "Box A",
Length = 21,
Width = 16,
Height = 20,
Quantity = 500,
Rotatable = true
},
new() {
SkuId = "B",
Name = "Box B",
Length = 52,
Width = 33,
Height = 20,
Quantity = 500,
Rotatable = true
}
};

var pallet = new Pallet("Standard Pallet", 120, 100, 14);

var strategy = new BLFGenerationStrategy();
var options = new GenerationOptions { };

var layers = strategy.Generate(skus, pallet, options);

Assert.NotEmpty(layers);
layers.Sort((l1, l2) => l1.Items.Count.CompareTo(l2.Items.Count));
Assert.Equal(33, layers.Last().Items.Count);
layers.Sort((l1, l2) => l1.Metadata.Utilization.CompareTo(l2.Metadata.Utilization));
Assert.Equal(0.942, layers.Last().Metadata.Utilization, 3);
}

[Fact]
public void Generate_ShouldRespectSKUQuantityLimits()
{
var skus = new List<SKU>
{
new SKU
{
SkuId = "X",
Name = "Tiny Box",
Length = 100,
Width = 100,
Height = 50,
Quantity = 2,
Rotatable = true
}
};

var pallet = new Pallet("Interesting Pallet", 300, 200, 14);
var strategy = new BLFGenerationStrategy();

var layers = strategy.Generate(skus, pallet, new GenerationOptions { });
var totalPlaced = 0;

foreach (var layer in layers)
totalPlaced += layer.Items.Count(i => i.SkuType.SkuId == "X");

Assert.True(totalPlaced <= 2);
}
}
}
Loading
Loading