refactor(ExcelIO): delete old attribute-based infrastructure
- Remove OutputColumnAttribute, OutputTableAttribute, OutputColumnCache - Remove AttributeTableWriter and ColumnFormatter - Remove duplicate ExcelFormats from Mapping (use Formatting version) - Remove OutputColumn model - Add FilterEntryMaps for criteria sheet filter models - Update CriteriaSheetGenerator to use FluentTableWriter - Remove attributes from filter entry models (now use fluent maps) - Update DI to register filter entry maps and remove old services - Update tests to use new fluent infrastructure - Delete obsolete test files for removed infrastructure Task 16 of fluent-excel-mapping-implementation plan.
This commit is contained in:
@@ -1,187 +0,0 @@
|
||||
using ClosedXML.Excel;
|
||||
using JdeScoping.ExcelIO.Attributes;
|
||||
using JdeScoping.ExcelIO.Generators;
|
||||
using JdeScoping.ExcelIO.Helpers;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace JdeScoping.ExcelIO.Tests;
|
||||
|
||||
public class AttributeTableWriterTests
|
||||
{
|
||||
private readonly OutputColumnCache _cache = new();
|
||||
private readonly AttributeTableWriter _writer;
|
||||
|
||||
public AttributeTableWriterTests()
|
||||
{
|
||||
_writer = new AttributeTableWriter(_cache);
|
||||
}
|
||||
|
||||
[OutputTable(TabName = "Test Items", TableName = "Test_Items", ShowHeader = false)]
|
||||
private class TestItem
|
||||
{
|
||||
[OutputColumn(Order = 10, HeaderText = "ID")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[OutputColumn(Order = 20, HeaderText = "Name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[OutputColumn(Order = 30, HeaderText = "Value")]
|
||||
public decimal Value { get; set; }
|
||||
}
|
||||
|
||||
[OutputTable(TabName = "Wrapped Table", TableName = "Wrapped_Table")]
|
||||
private class WrappedItem
|
||||
{
|
||||
[OutputColumn(Order = 10, HeaderText = "Description", WrapText = true, AutoWidth = false, Width = 65)]
|
||||
public string Description { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private class NoAttributeItem
|
||||
{
|
||||
public string Data { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTable_CreatesTableWithCorrectColumns()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var data = new List<TestItem>
|
||||
{
|
||||
new() { Id = 1, Name = "Item 1", Value = 10.5m },
|
||||
new() { Id = 2, Name = "Item 2", Value = 20.5m }
|
||||
};
|
||||
|
||||
var table = _writer.WriteTable(worksheet, 1, 1, data);
|
||||
|
||||
table.ShouldNotBeNull();
|
||||
table.ColumnCount().ShouldBe(3);
|
||||
table.RowCount().ShouldBe(3); // Header + 2 data rows
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTable_UsesLight18TableStyle()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var data = new List<TestItem> { new() { Id = 1, Name = "Test", Value = 100m } };
|
||||
|
||||
var table = _writer.WriteTable(worksheet, 1, 1, data);
|
||||
|
||||
table.ShouldNotBeNull();
|
||||
table.Theme.ShouldBe(XLTableTheme.TableStyleLight18);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTable_SetsColumnHeaders()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var data = new List<TestItem> { new() { Id = 1, Name = "Test", Value = 100m } };
|
||||
|
||||
_writer.WriteTable(worksheet, 1, 1, data);
|
||||
|
||||
worksheet.Cell(1, 1).Value.GetText().ShouldBe("ID");
|
||||
worksheet.Cell(1, 2).Value.GetText().ShouldBe("Name");
|
||||
worksheet.Cell(1, 3).Value.GetText().ShouldBe("Value");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTable_WritesDataRows()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var data = new List<TestItem>
|
||||
{
|
||||
new() { Id = 1, Name = "Item 1", Value = 10.5m },
|
||||
new() { Id = 2, Name = "Item 2", Value = 20.5m }
|
||||
};
|
||||
|
||||
_writer.WriteTable(worksheet, 1, 1, data);
|
||||
|
||||
worksheet.Cell(2, 1).Value.GetNumber().ShouldBe(1);
|
||||
worksheet.Cell(2, 2).Value.GetText().ShouldBe("Item 1");
|
||||
worksheet.Cell(2, 3).Value.GetNumber().ShouldBe(10.5);
|
||||
worksheet.Cell(3, 1).Value.GetNumber().ShouldBe(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTable_WithShowHeader_CreatesMergedHeader()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var data = new List<TestItem> { new() { Id = 1, Name = "Test", Value = 100m } };
|
||||
|
||||
_writer.WriteTable(worksheet, 1, 1, data, showHeader: true, headerText: "Test Header");
|
||||
|
||||
// First row should be merged header
|
||||
var headerRange = worksheet.Range(1, 1, 1, 3);
|
||||
headerRange.IsMerged().ShouldBeTrue();
|
||||
worksheet.Cell(1, 1).Value.GetText().ShouldBe("Test Header");
|
||||
|
||||
// Column headers should be on row 2
|
||||
worksheet.Cell(2, 1).Value.GetText().ShouldBe("ID");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTable_EmptyData_CreatesTableWithHeaderOnly()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var data = new List<TestItem>();
|
||||
|
||||
var table = _writer.WriteTable(worksheet, 1, 1, data);
|
||||
|
||||
table.ShouldNotBeNull();
|
||||
// Table should exist with headers
|
||||
table.ColumnCount().ShouldBe(3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTable_NoAttributes_ReturnsNull()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var data = new List<NoAttributeItem> { new() { Data = "Test" } };
|
||||
|
||||
var table = _writer.WriteTable(worksheet, 1, 1, data);
|
||||
|
||||
table.ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTable_WrappedColumn_SetsFixedWidth()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var data = new List<WrappedItem> { new() { Description = "Long description text" } };
|
||||
|
||||
_writer.WriteTable(worksheet, 1, 1, data);
|
||||
|
||||
worksheet.Column(1).Width.ShouldBe(65);
|
||||
worksheet.Column(1).Style.Alignment.WrapText.ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteTable_TableNameOverride_UsesProvidedName()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var data = new List<TestItem> { new() { Id = 1, Name = "Test", Value = 100m } };
|
||||
|
||||
var table = _writer.WriteTable(worksheet, 1, 1, data, tableNameOverride: "Custom_Table");
|
||||
|
||||
table.ShouldNotBeNull();
|
||||
table.Name.ShouldBe("Custom_Table");
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
using ClosedXML.Excel;
|
||||
using JdeScoping.ExcelIO.Attributes;
|
||||
using JdeScoping.ExcelIO.Formatting;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace JdeScoping.ExcelIO.Tests;
|
||||
|
||||
public class ColumnFormatterTests
|
||||
{
|
||||
[Fact]
|
||||
public void ApplyColumnFormat_AutoWidth_AdjustsToContents()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
worksheet.Cell(1, 1).Value = "Some Text Value";
|
||||
|
||||
var attr = new OutputColumnAttribute
|
||||
{
|
||||
AutoWidth = true,
|
||||
Format = OutputColumnAttribute.StdFormat
|
||||
};
|
||||
|
||||
ColumnFormatter.ApplyColumnFormat(worksheet.Column(1), attr);
|
||||
|
||||
// Width should be greater than default after adjustment
|
||||
worksheet.Column(1).Width.ShouldBeGreaterThan(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyColumnFormat_FixedWidth_SetsExactWidth()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var attr = new OutputColumnAttribute
|
||||
{
|
||||
AutoWidth = false,
|
||||
Width = 50.0,
|
||||
Format = OutputColumnAttribute.StdFormat
|
||||
};
|
||||
|
||||
ColumnFormatter.ApplyColumnFormat(worksheet.Column(1), attr);
|
||||
|
||||
worksheet.Column(1).Width.ShouldBe(50.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyColumnFormat_WrapText_EnablesWrapping()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var attr = new OutputColumnAttribute
|
||||
{
|
||||
WrapText = true,
|
||||
AutoWidth = false,
|
||||
Width = 65.0,
|
||||
Format = OutputColumnAttribute.StdFormat
|
||||
};
|
||||
|
||||
ColumnFormatter.ApplyColumnFormat(worksheet.Column(1), attr);
|
||||
|
||||
worksheet.Column(1).Style.Alignment.WrapText.ShouldBeTrue();
|
||||
worksheet.Column(1).Width.ShouldBe(65.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyColumnFormat_DateFormat_AppliesCorrectFormat()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var attr = new OutputColumnAttribute
|
||||
{
|
||||
AutoWidth = false,
|
||||
Width = 20.0,
|
||||
Format = OutputColumnAttribute.DateFormat
|
||||
};
|
||||
|
||||
ColumnFormatter.ApplyColumnFormat(worksheet.Column(1), attr);
|
||||
|
||||
worksheet.Column(1).Style.NumberFormat.Format.ShouldBe(OutputColumnAttribute.DateFormat);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyColumnFormat_TimestampFormat_AppliesCorrectFormat()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
|
||||
var attr = new OutputColumnAttribute
|
||||
{
|
||||
AutoWidth = false,
|
||||
Width = 25.0,
|
||||
Format = OutputColumnAttribute.TimestampFormat
|
||||
};
|
||||
|
||||
ColumnFormatter.ApplyColumnFormat(worksheet.Column(1), attr);
|
||||
|
||||
worksheet.Column(1).Style.NumberFormat.Format.ShouldBe(OutputColumnAttribute.TimestampFormat);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AutoFitWithPadding_AppliesPaddingFactor()
|
||||
{
|
||||
using var workbook = new XLWorkbook();
|
||||
var worksheet = workbook.Worksheets.Add("Test");
|
||||
worksheet.Cell(1, 1).Value = "Some Text";
|
||||
|
||||
ColumnFormatter.AutoFitWithPadding(worksheet.Column(1), 1.30);
|
||||
|
||||
// Width should be greater than 0 and include padding
|
||||
worksheet.Column(1).Width.ShouldBeGreaterThan(0);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
using ClosedXML.Excel;
|
||||
using JdeScoping.ExcelIO.Options;
|
||||
using JdeScoping.ExcelIO.Generators;
|
||||
using JdeScoping.ExcelIO.Helpers;
|
||||
using JdeScoping.ExcelIO.Mapping;
|
||||
using JdeScoping.ExcelIO.Mapping.Maps;
|
||||
using JdeScoping.ExcelIO.Models.Reporting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Shouldly;
|
||||
@@ -21,11 +22,25 @@ public class CriteriaSheetGeneratorTests
|
||||
CriteriaSheetPassword = "TestPassword"
|
||||
});
|
||||
|
||||
var cache = new OutputColumnCache();
|
||||
var tableWriter = new AttributeTableWriter(cache);
|
||||
var registry = CreateTestRegistry();
|
||||
var tableWriter = new FluentTableWriter(registry);
|
||||
_generator = new CriteriaSheetGenerator(_options, tableWriter);
|
||||
}
|
||||
|
||||
private static ExcelMapRegistry CreateTestRegistry()
|
||||
{
|
||||
var registry = new ExcelMapRegistry();
|
||||
registry.Register(new TimespanFilterMap());
|
||||
registry.Register(new WorkOrderFilterEntryMap());
|
||||
registry.Register(new ItemNumberFilterEntryMap());
|
||||
registry.Register(new ProfitCenterFilterEntryMap());
|
||||
registry.Register(new WorkCenterFilterEntryMap());
|
||||
registry.Register(new OperatorFilterEntryMap());
|
||||
registry.Register(new ComponentLotFilterEntryMap());
|
||||
registry.Register(new ItemOperationMisFilterEntryMap());
|
||||
return registry;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Generate_CreatesSearchCriteriaSheet()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using ClosedXML.Excel;
|
||||
using JdeScoping.ExcelIO.Options;
|
||||
using JdeScoping.ExcelIO.Generators;
|
||||
using JdeScoping.ExcelIO.Helpers;
|
||||
using JdeScoping.ExcelIO.Mapping;
|
||||
using JdeScoping.ExcelIO.Mapping.Maps;
|
||||
using JdeScoping.ExcelIO.Models.Reporting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
@@ -9,6 +10,10 @@ using NSubstitute;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
using SearchResult = JdeScoping.Core.Models.SearchResults.SearchResult;
|
||||
using MisSearchResult = JdeScoping.Core.Models.SearchResults.MisSearchResult;
|
||||
using MisNonMatchSearchResult = JdeScoping.Core.Models.SearchResults.MisNonMatchSearchResult;
|
||||
|
||||
namespace JdeScoping.ExcelIO.Tests;
|
||||
|
||||
/// <summary>
|
||||
@@ -29,11 +34,33 @@ public class ExcelExportIntegrationTests
|
||||
DataSheetPassword = "TestDataPass"
|
||||
});
|
||||
|
||||
var cache = new OutputColumnCache();
|
||||
var tableWriter = new AttributeTableWriter(cache);
|
||||
var registry = CreateTestRegistry();
|
||||
var tableWriter = new FluentTableWriter(registry);
|
||||
var criteriaGenerator = new CriteriaSheetGenerator(_options, tableWriter);
|
||||
|
||||
_service = new ExcelExportService(_logger, _options, criteriaGenerator, tableWriter);
|
||||
_service = new ExcelExportService(_logger, _options, criteriaGenerator, tableWriter, registry);
|
||||
}
|
||||
|
||||
private static ExcelMapRegistry CreateTestRegistry()
|
||||
{
|
||||
var registry = new ExcelMapRegistry();
|
||||
|
||||
// Search result maps
|
||||
registry.Register(new SearchResultMap());
|
||||
registry.Register(new MisSearchResultMap());
|
||||
registry.Register(new MisNonMatchSearchResultMap());
|
||||
|
||||
// Filter entry maps
|
||||
registry.Register(new TimespanFilterMap());
|
||||
registry.Register(new WorkOrderFilterEntryMap());
|
||||
registry.Register(new ItemNumberFilterEntryMap());
|
||||
registry.Register(new ProfitCenterFilterEntryMap());
|
||||
registry.Register(new WorkCenterFilterEntryMap());
|
||||
registry.Register(new OperatorFilterEntryMap());
|
||||
registry.Register(new ComponentLotFilterEntryMap());
|
||||
registry.Register(new ItemOperationMisFilterEntryMap());
|
||||
|
||||
return registry;
|
||||
}
|
||||
|
||||
#region Sheet Count Tests
|
||||
@@ -387,10 +414,13 @@ public class ExcelExportIntegrationTests
|
||||
public async Task GenerateAsync_SearchResults_ContainsCorrectData()
|
||||
{
|
||||
var search = CreateMinimalSearchModel();
|
||||
var searchResult = CreateSampleSearchResult();
|
||||
searchResult.WorkOrderNumber = 99999;
|
||||
searchResult.ItemNumber = "TEST-ITEM-001";
|
||||
searchResult.LotNumber = "LOT-999";
|
||||
var searchResult = new SearchResult
|
||||
{
|
||||
WorkOrderNumber = 99999,
|
||||
ItemNumber = "TEST-ITEM-001",
|
||||
LotNumber = "LOT-999",
|
||||
Flagged = true
|
||||
};
|
||||
search.Results.Add(searchResult);
|
||||
|
||||
var result = await _service.GenerateAsync(search);
|
||||
@@ -408,9 +438,16 @@ public class ExcelExportIntegrationTests
|
||||
[Fact]
|
||||
public async Task GenerateAsync_MisInfo_ContainsCorrectData()
|
||||
{
|
||||
var search = CreateSearchModelWithMisData();
|
||||
search.MisResults![0].ItemNumber = "MIS-ITEM-001";
|
||||
search.MisResults[0].MisNumber = "MIS-12345";
|
||||
var search = CreateMinimalSearchModel();
|
||||
search.ExtractMisData = true;
|
||||
search.MisResults = [
|
||||
new MisSearchResult
|
||||
{
|
||||
ItemNumber = "MIS-ITEM-001",
|
||||
MisNumber = "MIS-12345"
|
||||
}
|
||||
];
|
||||
search.MisNonMatchResults = [];
|
||||
|
||||
var result = await _service.GenerateAsync(search);
|
||||
|
||||
@@ -426,9 +463,16 @@ public class ExcelExportIntegrationTests
|
||||
[Fact]
|
||||
public async Task GenerateAsync_Investigation_ContainsCorrectData()
|
||||
{
|
||||
var search = CreateSearchModelWithMisData();
|
||||
search.MisNonMatchResults![0].WorkOrderNumber = 77777;
|
||||
search.MisNonMatchResults[0].ItemNumber = "INV-ITEM-001";
|
||||
var search = CreateMinimalSearchModel();
|
||||
search.ExtractMisData = true;
|
||||
search.MisResults = [];
|
||||
search.MisNonMatchResults = [
|
||||
new MisNonMatchSearchResult
|
||||
{
|
||||
WorkOrderNumber = 77777,
|
||||
ItemNumber = "INV-ITEM-001"
|
||||
}
|
||||
];
|
||||
|
||||
var result = await _service.GenerateAsync(search);
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using ClosedXML.Excel;
|
||||
using JdeScoping.ExcelIO.Options;
|
||||
using JdeScoping.ExcelIO.Generators;
|
||||
using JdeScoping.ExcelIO.Helpers;
|
||||
using JdeScoping.ExcelIO.Mapping;
|
||||
using JdeScoping.ExcelIO.Mapping.Maps;
|
||||
using JdeScoping.ExcelIO.Models.Reporting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
@@ -9,6 +10,10 @@ using NSubstitute;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
using SearchResult = JdeScoping.Core.Models.SearchResults.SearchResult;
|
||||
using MisSearchResult = JdeScoping.Core.Models.SearchResults.MisSearchResult;
|
||||
using MisNonMatchSearchResult = JdeScoping.Core.Models.SearchResults.MisNonMatchSearchResult;
|
||||
|
||||
namespace JdeScoping.ExcelIO.Tests;
|
||||
|
||||
public class ExcelExportServiceTests
|
||||
@@ -26,11 +31,33 @@ public class ExcelExportServiceTests
|
||||
DataSheetPassword = "TestDataPass"
|
||||
});
|
||||
|
||||
var cache = new OutputColumnCache();
|
||||
var tableWriter = new AttributeTableWriter(cache);
|
||||
var registry = CreateTestRegistry();
|
||||
var tableWriter = new FluentTableWriter(registry);
|
||||
var criteriaGenerator = new CriteriaSheetGenerator(_options, tableWriter);
|
||||
|
||||
_service = new ExcelExportService(_logger, _options, criteriaGenerator, tableWriter);
|
||||
_service = new ExcelExportService(_logger, _options, criteriaGenerator, tableWriter, registry);
|
||||
}
|
||||
|
||||
private static ExcelMapRegistry CreateTestRegistry()
|
||||
{
|
||||
var registry = new ExcelMapRegistry();
|
||||
|
||||
// Search result maps
|
||||
registry.Register(new SearchResultMap());
|
||||
registry.Register(new MisSearchResultMap());
|
||||
registry.Register(new MisNonMatchSearchResultMap());
|
||||
|
||||
// Filter entry maps
|
||||
registry.Register(new TimespanFilterMap());
|
||||
registry.Register(new WorkOrderFilterEntryMap());
|
||||
registry.Register(new ItemNumberFilterEntryMap());
|
||||
registry.Register(new ProfitCenterFilterEntryMap());
|
||||
registry.Register(new WorkCenterFilterEntryMap());
|
||||
registry.Register(new OperatorFilterEntryMap());
|
||||
registry.Register(new ComponentLotFilterEntryMap());
|
||||
registry.Register(new ItemOperationMisFilterEntryMap());
|
||||
|
||||
return registry;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using JdeScoping.ExcelIO.Models.Reporting;
|
||||
using JdeScoping.Core.Models.SearchResults;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using ClosedXML.Excel;
|
||||
using JdeScoping.ExcelIO.Options;
|
||||
using JdeScoping.ExcelIO.Formatting;
|
||||
using JdeScoping.ExcelIO.Generators;
|
||||
using JdeScoping.ExcelIO.Helpers;
|
||||
using JdeScoping.ExcelIO.Mapping;
|
||||
using JdeScoping.ExcelIO.Mapping.Maps;
|
||||
using JdeScoping.ExcelIO.Models.Reporting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
@@ -10,6 +10,11 @@ using NSubstitute;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
using ExcelFormats = JdeScoping.ExcelIO.Formatting.ExcelFormats;
|
||||
using SearchResult = JdeScoping.Core.Models.SearchResults.SearchResult;
|
||||
using MisSearchResult = JdeScoping.Core.Models.SearchResults.MisSearchResult;
|
||||
using MisNonMatchSearchResult = JdeScoping.Core.Models.SearchResults.MisNonMatchSearchResult;
|
||||
|
||||
namespace JdeScoping.ExcelIO.Tests;
|
||||
|
||||
/// <summary>
|
||||
@@ -30,11 +35,33 @@ public class LegacyComparisonTests
|
||||
DataSheetPassword = "JDESCOPINGTOOL"
|
||||
});
|
||||
|
||||
var cache = new OutputColumnCache();
|
||||
var tableWriter = new AttributeTableWriter(cache);
|
||||
var registry = CreateTestRegistry();
|
||||
var tableWriter = new FluentTableWriter(registry);
|
||||
var criteriaGenerator = new CriteriaSheetGenerator(options, tableWriter);
|
||||
|
||||
_service = new ExcelExportService(logger, options, criteriaGenerator, tableWriter);
|
||||
_service = new ExcelExportService(logger, options, criteriaGenerator, tableWriter, registry);
|
||||
}
|
||||
|
||||
private static ExcelMapRegistry CreateTestRegistry()
|
||||
{
|
||||
var registry = new ExcelMapRegistry();
|
||||
|
||||
// Search result maps
|
||||
registry.Register(new SearchResultMap());
|
||||
registry.Register(new MisSearchResultMap());
|
||||
registry.Register(new MisNonMatchSearchResultMap());
|
||||
|
||||
// Filter entry maps
|
||||
registry.Register(new TimespanFilterMap());
|
||||
registry.Register(new WorkOrderFilterEntryMap());
|
||||
registry.Register(new ItemNumberFilterEntryMap());
|
||||
registry.Register(new ProfitCenterFilterEntryMap());
|
||||
registry.Register(new WorkCenterFilterEntryMap());
|
||||
registry.Register(new OperatorFilterEntryMap());
|
||||
registry.Register(new ComponentLotFilterEntryMap());
|
||||
registry.Register(new ItemOperationMisFilterEntryMap());
|
||||
|
||||
return registry;
|
||||
}
|
||||
|
||||
#region Search Results Column Order Tests
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using JdeScoping.ExcelIO.Formatting;
|
||||
using JdeScoping.ExcelIO.Mapping;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
@@ -23,7 +24,7 @@ public class ExcelClassMapTests
|
||||
|
||||
Map(x => x.Id).Order(10).Header("ID Number");
|
||||
Map(x => x.Name).Order(20).Header("Full Name");
|
||||
Map(x => x.CreatedAt).Order(30).Header("Created").Format(ExcelFormats.Timestamp);
|
||||
Map(x => x.CreatedAt).Order(30).Header("Created").Format(ExcelFormats.TimestampFormat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +72,7 @@ public class ExcelClassMapTests
|
||||
var map = new TestModelMap();
|
||||
var columns = map.Columns;
|
||||
|
||||
columns[2].Format.ShouldBe(ExcelFormats.Timestamp);
|
||||
columns[2].Format.ShouldBe(ExcelFormats.TimestampFormat);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
using JdeScoping.ExcelIO.Attributes;
|
||||
using JdeScoping.ExcelIO.Helpers;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace JdeScoping.ExcelIO.Tests;
|
||||
|
||||
public class OutputColumnCacheTests
|
||||
{
|
||||
private readonly OutputColumnCache _cache = new();
|
||||
|
||||
[OutputTable(TabName = "Test Table", TableName = "Test_Table")]
|
||||
private class TestModel
|
||||
{
|
||||
[OutputColumn(Order = 30, HeaderText = "Column C")]
|
||||
public string ColumnC { get; set; } = string.Empty;
|
||||
|
||||
[OutputColumn(Order = 10, HeaderText = "Column A")]
|
||||
public string ColumnA { get; set; } = string.Empty;
|
||||
|
||||
[OutputColumn(Order = 20, HeaderText = "Column B")]
|
||||
public string ColumnB { get; set; } = string.Empty;
|
||||
|
||||
public string NonOutputColumn { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private class TieBreakModel
|
||||
{
|
||||
[OutputColumn(Order = 10, HeaderText = "Zebra")]
|
||||
public string Zebra { get; set; } = string.Empty;
|
||||
|
||||
[OutputColumn(Order = 10, HeaderText = "Apple")]
|
||||
public string Apple { get; set; } = string.Empty;
|
||||
|
||||
[OutputColumn(Order = 10, HeaderText = "Mango")]
|
||||
public string Mango { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private class EmptyModel
|
||||
{
|
||||
public string NoAttributes { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetColumns_ReturnsColumnsOrderedByOrderProperty()
|
||||
{
|
||||
var columns = _cache.GetColumns<TestModel>();
|
||||
|
||||
columns.Count.ShouldBe(3);
|
||||
columns[0].Attribute.HeaderText.ShouldBe("Column A");
|
||||
columns[1].Attribute.HeaderText.ShouldBe("Column B");
|
||||
columns[2].Attribute.HeaderText.ShouldBe("Column C");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetColumns_TieBreaksAlphabeticallyByPropertyName()
|
||||
{
|
||||
var columns = _cache.GetColumns<TieBreakModel>();
|
||||
|
||||
columns.Count.ShouldBe(3);
|
||||
// All have Order=10, so should be sorted by property name
|
||||
columns[0].Name.ShouldBe("Apple");
|
||||
columns[1].Name.ShouldBe("Mango");
|
||||
columns[2].Name.ShouldBe("Zebra");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetColumns_ExcludesPropertiesWithoutAttribute()
|
||||
{
|
||||
var columns = _cache.GetColumns<TestModel>();
|
||||
|
||||
columns.Count.ShouldBe(3);
|
||||
columns.ShouldNotContain(c => c.Name == "NonOutputColumn");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetColumns_ReturnsEmptyForEmptyModel()
|
||||
{
|
||||
var columns = _cache.GetColumns<EmptyModel>();
|
||||
|
||||
columns.Count.ShouldBe(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetColumns_CachesResults()
|
||||
{
|
||||
var columns1 = _cache.GetColumns<TestModel>();
|
||||
var columns2 = _cache.GetColumns<TestModel>();
|
||||
|
||||
ReferenceEquals(columns1, columns2).ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetColumns_ByType_ReturnsCorrectColumns()
|
||||
{
|
||||
var columns = _cache.GetColumns(typeof(TestModel));
|
||||
|
||||
columns.Count.ShouldBe(3);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user