feat: load legacy Cuts and Res runtime assets
This commit is contained in:
@@ -0,0 +1,578 @@
|
||||
using System.Text;
|
||||
using MMoneyCoderSharp.Data;
|
||||
|
||||
namespace MBN_STOCK_WEBVIEW.LegacyApplication.Tests;
|
||||
|
||||
public sealed class LegacyRuntimeUiCatalogLoaderTests
|
||||
{
|
||||
private static readonly Encoding Cp949 = CreateCp949Encoding();
|
||||
|
||||
[Fact]
|
||||
public void ConfiguredLegacyBinDebugFiles_MatchEveryRuntimeProjection()
|
||||
{
|
||||
var legacyBinDebug = Environment.GetEnvironmentVariable(
|
||||
"MBN_STOCK_N_LEGACY_BIN_DEBUG");
|
||||
if (string.IsNullOrWhiteSpace(legacyBinDebug))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var composition = LegacyRuntimeUiCatalogLoader.ResolveFromBaseDirectory(
|
||||
legacyBinDebug);
|
||||
|
||||
Assert.Empty(composition.Warnings);
|
||||
AssertRuntimeFixedFile(
|
||||
legacyBinDebug,
|
||||
"해외.ini",
|
||||
LegacyFixedMarket.Overseas,
|
||||
LegacyFixedActionCatalog.ExpectedOverseasCount,
|
||||
composition.FixedCatalog);
|
||||
AssertRuntimeFixedFile(
|
||||
legacyBinDebug,
|
||||
"환율.ini",
|
||||
LegacyFixedMarket.Exchange,
|
||||
LegacyFixedActionCatalog.ExpectedExchangeCount,
|
||||
composition.FixedCatalog);
|
||||
AssertRuntimeFixedFile(
|
||||
legacyBinDebug,
|
||||
"지수.ini",
|
||||
LegacyFixedMarket.Index,
|
||||
LegacyFixedActionCatalog.ExpectedIndexCount,
|
||||
composition.FixedCatalog);
|
||||
AssertRuntimeIndustryFile(
|
||||
legacyBinDebug,
|
||||
"업종_코스피.ini",
|
||||
IndustryMarket.Kospi,
|
||||
composition.IndustryLayout);
|
||||
AssertRuntimeIndustryFile(
|
||||
legacyBinDebug,
|
||||
"업종_코스닥.ini",
|
||||
IndustryMarket.Kosdaq,
|
||||
composition.IndustryLayout);
|
||||
AssertRuntimeComparisonFile(
|
||||
legacyBinDebug,
|
||||
composition.ComparisonLayout);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuntimeFiles_ControlOnlyTrustedDisplayOrder()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
var fixedOrders = Enum.GetValues<LegacyFixedMarket>()
|
||||
.ToDictionary(
|
||||
market => market,
|
||||
market => LegacyFixedActionCatalog.Default.GetActions(market)
|
||||
.Reverse()
|
||||
.ToArray());
|
||||
var kospi = LegacyIndustryActionCatalog.GetActions(IndustryMarket.Kospi)
|
||||
.Reverse()
|
||||
.ToArray();
|
||||
var kosdaq = LegacyIndustryActionCatalog.GetActions(IndustryMarket.Kosdaq)
|
||||
.Reverse()
|
||||
.ToArray();
|
||||
var targets = LegacyComparisonWorkflowCatalog.FixedTargets
|
||||
.Reverse()
|
||||
.ToArray();
|
||||
var directActions = LegacyComparisonWorkflowCatalog.Actions
|
||||
.Where(action => action.Kind != LegacyComparisonActionKind.Return)
|
||||
.Reverse()
|
||||
.ToArray();
|
||||
var returnActions = LegacyComparisonWorkflowCatalog.Actions
|
||||
.Where(action => action.Kind == LegacyComparisonActionKind.Return)
|
||||
.Reverse()
|
||||
.ToArray();
|
||||
|
||||
WriteAllValidFiles(
|
||||
directory.Path,
|
||||
fixedOrders,
|
||||
kospi,
|
||||
kosdaq,
|
||||
targets,
|
||||
directActions,
|
||||
returnActions,
|
||||
returnSectionFirst: true);
|
||||
|
||||
var composition = LegacyRuntimeUiCatalogLoader.ResolveFromBaseDirectory(
|
||||
directory.Path);
|
||||
|
||||
Assert.Empty(composition.Warnings);
|
||||
foreach (var market in Enum.GetValues<LegacyFixedMarket>())
|
||||
{
|
||||
Assert.Equal(
|
||||
FlattenForIni(fixedOrders[market]).Select(action => action.Id),
|
||||
composition.FixedCatalog.GetActions(market).Select(action => action.Id));
|
||||
}
|
||||
|
||||
Assert.Equal(
|
||||
kospi.Select(action => action.ActionId),
|
||||
composition.IndustryLayout.GetActions(IndustryMarket.Kospi)
|
||||
.Select(action => action.ActionId));
|
||||
Assert.Equal(
|
||||
kosdaq.Select(action => action.ActionId),
|
||||
composition.IndustryLayout.GetActions(IndustryMarket.Kosdaq)
|
||||
.Select(action => action.ActionId));
|
||||
Assert.Equal(
|
||||
targets.Select(target => target.TargetId),
|
||||
composition.ComparisonLayout.FixedTargets.Select(target => target.TargetId));
|
||||
Assert.Equal(
|
||||
returnActions.Select(action => action.ActionId)
|
||||
.Concat(directActions.Select(action => action.ActionId)),
|
||||
composition.ComparisonLayout.CreateActionViews(null, null)
|
||||
.Select(action => action.ActionId));
|
||||
|
||||
var industryWorkflow = new LegacyIndustrySelectionWorkflow(
|
||||
new EmptyIndustrySelectionService(),
|
||||
actionLayout: composition.IndustryLayout);
|
||||
Assert.Equal(
|
||||
kospi.Select(action => action.ActionId),
|
||||
industryWorkflow.ResetForTabActivation(IndustryMarket.Kospi)
|
||||
.Actions.Select(action => action.ActionId));
|
||||
|
||||
var comparisonWorkflow = new LegacyComparisonWorkflowController(
|
||||
new EmptyComparisonDataService(),
|
||||
new EmptyComparisonPairStore(),
|
||||
composition.ComparisonLayout);
|
||||
Assert.Equal(
|
||||
targets.Select(target => target.DisplayName),
|
||||
comparisonWorkflow.Current.FixedTargets.Select(target => target.DisplayName));
|
||||
Assert.Equal(
|
||||
returnActions.Select(action => action.ActionId)
|
||||
.Concat(directActions.Select(action => action.ActionId)),
|
||||
comparisonWorkflow.Current.Actions.Select(action => action.ActionId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownFixedRow_FallsBackWithoutRegisteringAnAction()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
WriteAllValidFiles(directory.Path);
|
||||
WriteFixedFile(
|
||||
directory.Path,
|
||||
LegacyFixedMarket.Overseas,
|
||||
LegacyFixedActionCatalog.Default.GetActions(LegacyFixedMarket.Overseas),
|
||||
(action, index) => index == 0 ? "untrusted-new-action" : action.Label);
|
||||
|
||||
var composition = LegacyRuntimeUiCatalogLoader.ResolveFromBaseDirectory(
|
||||
directory.Path);
|
||||
|
||||
var warning = Assert.Single(composition.Warnings);
|
||||
Assert.Equal("해외.ini", warning.FileName);
|
||||
Assert.Equal(LegacyRuntimeUiCatalogFailure.UnknownEntry, warning.Failure);
|
||||
Assert.Equal(
|
||||
LegacyFixedActionCatalog.Default.GetActions(LegacyFixedMarket.Overseas)
|
||||
.Select(action => action.Id),
|
||||
composition.FixedCatalog.GetActions(LegacyFixedMarket.Overseas)
|
||||
.Select(action => action.Id));
|
||||
Assert.DoesNotContain(
|
||||
composition.FixedCatalog.Actions,
|
||||
action => string.Equals(
|
||||
action.Label,
|
||||
"untrusted-new-action",
|
||||
StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExcessDuplicateRow_FallsBackWithDuplicateWarning()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
WriteAllValidFiles(directory.Path);
|
||||
WriteFixedFile(
|
||||
directory.Path,
|
||||
LegacyFixedMarket.Exchange,
|
||||
LegacyFixedActionCatalog.Default.GetActions(LegacyFixedMarket.Exchange),
|
||||
appendDuplicate: true);
|
||||
|
||||
var composition = LegacyRuntimeUiCatalogLoader.ResolveFromBaseDirectory(
|
||||
directory.Path);
|
||||
|
||||
var warning = Assert.Single(composition.Warnings);
|
||||
Assert.Equal("환율.ini", warning.FileName);
|
||||
Assert.Equal(LegacyRuntimeUiCatalogFailure.DuplicateEntry, warning.Failure);
|
||||
Assert.Equal(
|
||||
LegacyFixedActionCatalog.Default.GetActions(LegacyFixedMarket.Exchange)
|
||||
.Select(action => action.Id),
|
||||
composition.FixedCatalog.GetActions(LegacyFixedMarket.Exchange)
|
||||
.Select(action => action.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidCp949_FallsBackOnlyForThatFile()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
WriteAllValidFiles(directory.Path);
|
||||
File.WriteAllBytes(
|
||||
System.IO.Path.Combine(directory.Path, "Res", "지수.ini"),
|
||||
[0x81]);
|
||||
|
||||
var composition = LegacyRuntimeUiCatalogLoader.ResolveFromBaseDirectory(
|
||||
directory.Path);
|
||||
|
||||
var warning = Assert.Single(composition.Warnings);
|
||||
Assert.Equal("지수.ini", warning.FileName);
|
||||
Assert.Equal(LegacyRuntimeUiCatalogFailure.InvalidEncoding, warning.Failure);
|
||||
Assert.Equal(
|
||||
LegacyFixedActionCatalog.Default.GetActions(LegacyFixedMarket.Index)
|
||||
.Select(action => action.Id),
|
||||
composition.FixedCatalog.GetActions(LegacyFixedMarket.Index)
|
||||
.Select(action => action.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RowLimit_FailsClosedBeforeCatalogJoin()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
WriteAllValidFiles(directory.Path);
|
||||
var section = LegacyFixedActionCatalog.Default
|
||||
.GetActions(LegacyFixedMarket.Overseas)[0].Section;
|
||||
WriteCp949(
|
||||
System.IO.Path.Combine(directory.Path, "Res", "해외.ini"),
|
||||
[$"[{section}]", .. Enumerable.Range(1, 51).Select(index => $"row-{index}")]);
|
||||
|
||||
var composition = LegacyRuntimeUiCatalogLoader.ResolveFromBaseDirectory(
|
||||
directory.Path);
|
||||
|
||||
var warning = Assert.Single(composition.Warnings);
|
||||
Assert.Equal("해외.ini", warning.FileName);
|
||||
Assert.Equal(LegacyRuntimeUiCatalogFailure.TooManyRows, warning.Failure);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ComparisonDirectActionCannotBeReinterpretedAsAChildRow()
|
||||
{
|
||||
using var directory = new TemporaryDirectory();
|
||||
WriteAllValidFiles(directory.Path);
|
||||
var directActions = LegacyComparisonWorkflowCatalog.Actions
|
||||
.Where(action => action.Kind != LegacyComparisonActionKind.Return)
|
||||
.ToArray();
|
||||
var returnActions = LegacyComparisonWorkflowCatalog.Actions
|
||||
.Where(action => action.Kind == LegacyComparisonActionKind.Return)
|
||||
.ToArray();
|
||||
var lines = new List<string> { "[지수]" };
|
||||
lines.AddRange(LegacyComparisonWorkflowCatalog.FixedTargets
|
||||
.Select(target => target.DisplayName));
|
||||
foreach (var action in directActions)
|
||||
{
|
||||
lines.Add($"[{action.Label}]");
|
||||
}
|
||||
|
||||
lines.Add($"[{returnActions[0].Section}]");
|
||||
lines.Add(directActions[0].Label);
|
||||
lines.AddRange(returnActions.Select(action => action.Label));
|
||||
WriteCp949(
|
||||
System.IO.Path.Combine(directory.Path, "Res", "종목비교.ini"),
|
||||
lines);
|
||||
|
||||
var composition = LegacyRuntimeUiCatalogLoader.ResolveFromBaseDirectory(
|
||||
directory.Path);
|
||||
|
||||
var warning = Assert.Single(composition.Warnings);
|
||||
Assert.Equal("종목비교.ini", warning.FileName);
|
||||
Assert.Equal(LegacyRuntimeUiCatalogFailure.UnknownEntry, warning.Failure);
|
||||
Assert.Equal(
|
||||
LegacyComparisonWorkflowCatalog.Actions.Select(action => action.ActionId),
|
||||
composition.ComparisonLayout.CreateActionViews(null, null)
|
||||
.Select(action => action.ActionId));
|
||||
}
|
||||
|
||||
private static void WriteAllValidFiles(
|
||||
string baseDirectory,
|
||||
IReadOnlyDictionary<LegacyFixedMarket, LegacyFixedAction[]>? fixedOrders = null,
|
||||
IReadOnlyList<LegacyIndustryActionDefinition>? kospi = null,
|
||||
IReadOnlyList<LegacyIndustryActionDefinition>? kosdaq = null,
|
||||
IReadOnlyList<LegacyComparisonTarget>? targets = null,
|
||||
IReadOnlyList<LegacyComparisonActionDefinition>? directActions = null,
|
||||
IReadOnlyList<LegacyComparisonActionDefinition>? returnActions = null,
|
||||
bool returnSectionFirst = false)
|
||||
{
|
||||
Directory.CreateDirectory(System.IO.Path.Combine(baseDirectory, "Res"));
|
||||
foreach (var market in Enum.GetValues<LegacyFixedMarket>())
|
||||
{
|
||||
WriteFixedFile(
|
||||
baseDirectory,
|
||||
market,
|
||||
fixedOrders is not null && fixedOrders.TryGetValue(market, out var ordered)
|
||||
? ordered
|
||||
: LegacyFixedActionCatalog.Default.GetActions(market));
|
||||
}
|
||||
|
||||
WriteIndustryFile(
|
||||
baseDirectory,
|
||||
IndustryMarket.Kospi,
|
||||
kospi ?? LegacyIndustryActionCatalog.GetActions(IndustryMarket.Kospi));
|
||||
WriteIndustryFile(
|
||||
baseDirectory,
|
||||
IndustryMarket.Kosdaq,
|
||||
kosdaq ?? LegacyIndustryActionCatalog.GetActions(IndustryMarket.Kosdaq));
|
||||
WriteComparisonFile(
|
||||
baseDirectory,
|
||||
targets ?? LegacyComparisonWorkflowCatalog.FixedTargets,
|
||||
directActions ?? LegacyComparisonWorkflowCatalog.Actions
|
||||
.Where(action => action.Kind != LegacyComparisonActionKind.Return)
|
||||
.ToArray(),
|
||||
returnActions ?? LegacyComparisonWorkflowCatalog.Actions
|
||||
.Where(action => action.Kind == LegacyComparisonActionKind.Return)
|
||||
.ToArray(),
|
||||
returnSectionFirst);
|
||||
}
|
||||
|
||||
private static void WriteFixedFile(
|
||||
string baseDirectory,
|
||||
LegacyFixedMarket market,
|
||||
IReadOnlyList<LegacyFixedAction> actions,
|
||||
Func<LegacyFixedAction, int, string>? labelSelector = null,
|
||||
bool appendDuplicate = false)
|
||||
{
|
||||
var lines = new List<string>();
|
||||
var rowIndex = 0;
|
||||
foreach (var section in actions.GroupBy(action => action.Section, StringComparer.Ordinal))
|
||||
{
|
||||
lines.Add($"[{section.Key}]");
|
||||
foreach (var action in section)
|
||||
{
|
||||
lines.Add(labelSelector?.Invoke(action, rowIndex) ?? action.Label);
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
if (appendDuplicate)
|
||||
{
|
||||
lines.Add(section.First().Label);
|
||||
appendDuplicate = false;
|
||||
}
|
||||
}
|
||||
|
||||
WriteCp949(
|
||||
System.IO.Path.Combine(baseDirectory, "Res", FixedFileName(market)),
|
||||
lines);
|
||||
}
|
||||
|
||||
private static IEnumerable<LegacyFixedAction> FlattenForIni(
|
||||
IEnumerable<LegacyFixedAction> actions) =>
|
||||
actions.GroupBy(action => action.Section, StringComparer.Ordinal)
|
||||
.SelectMany(group => group);
|
||||
|
||||
private static void WriteIndustryFile(
|
||||
string baseDirectory,
|
||||
IndustryMarket market,
|
||||
IReadOnlyList<LegacyIndustryActionDefinition> actions)
|
||||
{
|
||||
var section = market == IndustryMarket.Kospi ? "코스피" : "코스닥";
|
||||
WriteCp949(
|
||||
System.IO.Path.Combine(baseDirectory, "Res", IndustryFileName(market)),
|
||||
[$"[{section}]", .. actions.Select(action => action.Label)]);
|
||||
}
|
||||
|
||||
private static void WriteComparisonFile(
|
||||
string baseDirectory,
|
||||
IReadOnlyList<LegacyComparisonTarget> targets,
|
||||
IReadOnlyList<LegacyComparisonActionDefinition> directActions,
|
||||
IReadOnlyList<LegacyComparisonActionDefinition> returnActions,
|
||||
bool returnSectionFirst)
|
||||
{
|
||||
var lines = new List<string> { "[지수]" };
|
||||
lines.AddRange(targets.Select(target => target.DisplayName));
|
||||
void AddDirectSections()
|
||||
{
|
||||
foreach (var action in directActions)
|
||||
{
|
||||
lines.Add($"[{action.Label}]");
|
||||
}
|
||||
}
|
||||
|
||||
void AddReturnSection()
|
||||
{
|
||||
lines.Add($"[{returnActions[0].Section}]");
|
||||
lines.AddRange(returnActions.Select(action => action.Label));
|
||||
}
|
||||
|
||||
if (returnSectionFirst)
|
||||
{
|
||||
AddReturnSection();
|
||||
AddDirectSections();
|
||||
}
|
||||
else
|
||||
{
|
||||
AddDirectSections();
|
||||
AddReturnSection();
|
||||
}
|
||||
|
||||
WriteCp949(
|
||||
System.IO.Path.Combine(baseDirectory, "Res", "종목비교.ini"),
|
||||
lines);
|
||||
}
|
||||
|
||||
private static void WriteCp949(string path, IEnumerable<string> lines) =>
|
||||
File.WriteAllText(path, string.Join("\r\n", lines) + "\r\n", Cp949);
|
||||
|
||||
private static void AssertRuntimeFixedFile(
|
||||
string baseDirectory,
|
||||
string fileName,
|
||||
LegacyFixedMarket market,
|
||||
int expectedCount,
|
||||
LegacyFixedActionCatalog catalog)
|
||||
{
|
||||
var document = ReadTestIni(baseDirectory, fileName);
|
||||
var actions = catalog.GetActions(market);
|
||||
Assert.Equal(expectedCount, actions.Count);
|
||||
Assert.Equal(
|
||||
document.SelectMany(section => section.Rows),
|
||||
actions.Select(action => action.Label));
|
||||
Assert.Equal(
|
||||
document.SelectMany(section => section.Rows.Select(_ => section.Name)),
|
||||
actions.Select(action => action.Section));
|
||||
}
|
||||
|
||||
private static void AssertRuntimeIndustryFile(
|
||||
string baseDirectory,
|
||||
string fileName,
|
||||
IndustryMarket market,
|
||||
LegacyIndustryActionLayout layout)
|
||||
{
|
||||
var section = Assert.Single(ReadTestIni(baseDirectory, fileName));
|
||||
var actions = layout.GetActions(market);
|
||||
Assert.Equal(LegacyIndustryActionCatalog.ActionsPerMarket, actions.Count);
|
||||
Assert.Equal(section.Rows, actions.Select(action => action.Label));
|
||||
Assert.All(actions, action => Assert.Equal(section.Name, action.Section));
|
||||
}
|
||||
|
||||
private static void AssertRuntimeComparisonFile(
|
||||
string baseDirectory,
|
||||
LegacyComparisonUiLayout layout)
|
||||
{
|
||||
var document = ReadTestIni(baseDirectory, "종목비교.ini");
|
||||
Assert.Equal(6, document.Count);
|
||||
Assert.Equal(24, layout.FixedTargets.Count);
|
||||
Assert.Equal(
|
||||
document[0].Rows,
|
||||
layout.FixedTargets.Select(target => target.DisplayName));
|
||||
var expectedActions = document.Skip(1).SelectMany(section =>
|
||||
section.Rows.Count == 0
|
||||
? new[] { (Label: section.Name, Section: section.Name) }
|
||||
: section.Rows.Select(row => (Label: row, Section: section.Name)));
|
||||
var actualActions = layout.CreateActionViews(null, null);
|
||||
Assert.Equal(9, actualActions.Count);
|
||||
Assert.Equal(
|
||||
expectedActions,
|
||||
actualActions.Select(action => (action.Label, action.Section)));
|
||||
}
|
||||
|
||||
private static IReadOnlyList<TestIniSection> ReadTestIni(
|
||||
string baseDirectory,
|
||||
string fileName)
|
||||
{
|
||||
var sections = new List<TestIniSection>();
|
||||
List<string>? rows = null;
|
||||
foreach (var source in File.ReadAllLines(
|
||||
System.IO.Path.Combine(baseDirectory, "Res", fileName),
|
||||
Cp949))
|
||||
{
|
||||
var line = source.Trim();
|
||||
if (line.Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == '[' && line[^1] == ']')
|
||||
{
|
||||
rows = [];
|
||||
sections.Add(new TestIniSection(line[1..^1].Trim(), rows));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.NotNull(rows);
|
||||
rows.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
return sections;
|
||||
}
|
||||
|
||||
private static string FixedFileName(LegacyFixedMarket market) => market switch
|
||||
{
|
||||
LegacyFixedMarket.Overseas => "해외.ini",
|
||||
LegacyFixedMarket.Exchange => "환율.ini",
|
||||
LegacyFixedMarket.Index => "지수.ini",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(market), market, null)
|
||||
};
|
||||
|
||||
private static string IndustryFileName(IndustryMarket market) => market switch
|
||||
{
|
||||
IndustryMarket.Kospi => "업종_코스피.ini",
|
||||
IndustryMarket.Kosdaq => "업종_코스닥.ini",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(market), market, null)
|
||||
};
|
||||
|
||||
private static Encoding CreateCp949Encoding()
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
return Encoding.GetEncoding(
|
||||
949,
|
||||
EncoderFallback.ExceptionFallback,
|
||||
DecoderFallback.ExceptionFallback);
|
||||
}
|
||||
|
||||
private sealed class EmptyIndustrySelectionService : IIndustrySelectionService
|
||||
{
|
||||
public Task<IReadOnlyList<IndustrySelection>> GetAsync(
|
||||
IndustryMarket market,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<IReadOnlyList<IndustrySelection>>(
|
||||
Array.Empty<IndustrySelection>());
|
||||
}
|
||||
|
||||
private sealed class EmptyComparisonDataService : ILegacyComparisonDataService
|
||||
{
|
||||
public Task<IReadOnlyList<LegacyComparisonTarget>> SearchDomesticAsync(
|
||||
string query,
|
||||
int maximumResults,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<IReadOnlyList<LegacyComparisonTarget>>(
|
||||
Array.Empty<LegacyComparisonTarget>());
|
||||
|
||||
public Task<IReadOnlyList<LegacyComparisonTarget>> SearchWorldAsync(
|
||||
string query,
|
||||
int maximumResults,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<IReadOnlyList<LegacyComparisonTarget>>(
|
||||
Array.Empty<LegacyComparisonTarget>());
|
||||
|
||||
public Task<LegacyComparisonTarget?> ResolveStoredTargetAsync(
|
||||
LegacyComparisonStoredTargetReference target,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<LegacyComparisonTarget?>(null);
|
||||
}
|
||||
|
||||
private sealed class EmptyComparisonPairStore : ILegacyComparisonPairStore
|
||||
{
|
||||
public Task<byte[]?> ReadCp949Async(
|
||||
CancellationToken cancellationToken = default) =>
|
||||
Task.FromResult<byte[]?>(null);
|
||||
|
||||
public Task WriteCp949Async(
|
||||
IReadOnlyList<LegacyComparisonPairWriteRow> rows,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
Task.CompletedTask;
|
||||
}
|
||||
|
||||
private sealed class TemporaryDirectory : IDisposable
|
||||
{
|
||||
public TemporaryDirectory()
|
||||
{
|
||||
Path = System.IO.Path.Combine(
|
||||
System.IO.Path.GetTempPath(),
|
||||
$"MBN_STOCK_WEBVIEW_UI_INI_{Guid.NewGuid():N}");
|
||||
Directory.CreateDirectory(Path);
|
||||
}
|
||||
|
||||
public string Path { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Directory.Exists(Path))
|
||||
{
|
||||
Directory.Delete(Path, recursive: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed record TestIniSection(string Name, IReadOnlyList<string> Rows);
|
||||
}
|
||||
Reference in New Issue
Block a user