refactor(P5b-2): 출력 형식 교집합 로직을 ProviderRegistry로 추출 (매트릭스 필터 테스트화)
MainWindow.RefreshAvailableOutputFormats에 박혀 있던 '큐 전체 공통 출력' 교집합 계산을 ProviderRegistry.AvailableOutputsForFiles 순수 쿼리로 추출 — 코드비하인드 18줄 → 2줄, 헤드리스 테스트 가능. - ProviderRegistry.AvailableOutputsForFiles(sourcePaths): 비면 전체 출력, 아니면 OutputsForFile 교집합. - MainWindow: 인라인 교집합 루프 제거 → 레지스트리 메서드 호출. UI(콤보 빌드)는 그대로. - 테스트 2개: 빈 입력=전체, png+csv 혼합 시 jpg가 교집합에서 빠짐(매트릭스 필터 핵심 동작). 81 → 83개 테스트 전부 그린, 빌드 0경고/0오류.
This commit is contained in:
parent
ba5738e705
commit
e95ec967e6
3 changed files with 43 additions and 19 deletions
|
|
@ -952,25 +952,8 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
|
||||||
{
|
{
|
||||||
if (OutputFormatCombo is null) return;
|
if (OutputFormatCombo is null) return;
|
||||||
|
|
||||||
var engine = _engine;
|
var available = _engine.Providers.AvailableOutputsForFiles(
|
||||||
IReadOnlyCollection<string> available;
|
_activeQueue.Select(q => q.SourcePath).ToList());
|
||||||
|
|
||||||
if (_activeQueue.Count == 0)
|
|
||||||
{
|
|
||||||
available = engine.Providers.AllOutputExtensions;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HashSet<string>? intersection = null;
|
|
||||||
foreach (var item in _activeQueue)
|
|
||||||
{
|
|
||||||
var outs = engine.Providers.OutputsForFile(item.SourcePath);
|
|
||||||
var outSet = new HashSet<string>(outs, StringComparer.OrdinalIgnoreCase);
|
|
||||||
if (intersection is null) intersection = outSet;
|
|
||||||
else intersection.IntersectWith(outSet);
|
|
||||||
}
|
|
||||||
available = intersection ?? new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
var visible = AllFormats.Where(f => available.Contains(f.Extension)).ToList();
|
var visible = AllFormats.Where(f => available.Contains(f.Extension)).ToList();
|
||||||
if (visible.Count == 0)
|
if (visible.Count == 0)
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,25 @@ public sealed class ProviderRegistry
|
||||||
public IReadOnlyList<string> OutputsForFile(string sourcePath)
|
public IReadOnlyList<string> OutputsForFile(string sourcePath)
|
||||||
=> OutputsForInput(Path.GetExtension(sourcePath));
|
=> OutputsForInput(Path.GetExtension(sourcePath));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 여러 입력 파일이 '공통으로' 변환 가능한 출력 확장자(교집합). UI 매트릭스 자동 필터링의 핵심 —
|
||||||
|
/// 큐의 모든 파일을 같은 형식으로 변환할 수 있는 출력만 노출한다. 비어 있으면 전체 출력 확장자.
|
||||||
|
/// (MainWindow.RefreshAvailableOutputFormats에서 추출 — 순수 쿼리라 헤드리스 테스트 가능.)
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyCollection<string> AvailableOutputsForFiles(IReadOnlyCollection<string> sourcePaths)
|
||||||
|
{
|
||||||
|
if (sourcePaths.Count == 0) return AllOutputExtensions;
|
||||||
|
|
||||||
|
HashSet<string>? intersection = null;
|
||||||
|
foreach (var path in sourcePaths)
|
||||||
|
{
|
||||||
|
var outs = new HashSet<string>(OutputsForFile(path), StringComparer.OrdinalIgnoreCase);
|
||||||
|
if (intersection is null) intersection = outs;
|
||||||
|
else intersection.IntersectWith(outs);
|
||||||
|
}
|
||||||
|
return intersection ?? new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
public IReadOnlyCollection<string> AllInputExtensions => _allInputs;
|
public IReadOnlyCollection<string> AllInputExtensions => _allInputs;
|
||||||
|
|
||||||
public IReadOnlyCollection<string> AllOutputExtensions => _allOutputs;
|
public IReadOnlyCollection<string> AllOutputExtensions => _allOutputs;
|
||||||
|
|
|
||||||
|
|
@ -223,4 +223,26 @@ public class RegistryGraphIntegrationTests
|
||||||
Assert.Contains(".jpg", svgOut); // 멀티홉 svg→png→jpg
|
Assert.Contains(".jpg", svgOut); // 멀티홉 svg→png→jpg
|
||||||
Assert.Contains(".pdf", svgOut); // 직접
|
Assert.Contains(".pdf", svgOut); // 직접
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void AvailableOutputsForFiles_EmptyReturnsAllOutputs()
|
||||||
|
{
|
||||||
|
var reg = Everything2EverythingBootstrap.CreateDefault().Providers;
|
||||||
|
var all = reg.AvailableOutputsForFiles(System.Array.Empty<string>());
|
||||||
|
Assert.Equal(reg.AllOutputExtensions.Count, all.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void AvailableOutputsForFiles_IntersectsAcrossInputs()
|
||||||
|
{
|
||||||
|
var reg = Everything2EverythingBootstrap.CreateDefault().Providers;
|
||||||
|
|
||||||
|
// png 단독: jpg 등 이미지 출력 가능
|
||||||
|
var pngOnly = reg.AvailableOutputsForFiles(new[] { "a.png" });
|
||||||
|
Assert.Contains(".jpg", pngOnly);
|
||||||
|
|
||||||
|
// png + csv 혼합: csv는 jpg로 못 가므로 교집합에서 jpg가 빠진다(UI 매트릭스 자동 필터 핵심).
|
||||||
|
var mixed = reg.AvailableOutputsForFiles(new[] { "a.png", "b.csv" });
|
||||||
|
Assert.DoesNotContain(".jpg", mixed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue