refactor(dotnet): normalize learning dataset export inputs
This commit is contained in:
@@ -11,7 +11,9 @@ public sealed class LearningDatasetService
|
|||||||
|
|
||||||
public async Task<string> ExportJsonAsync(string outputPath, int limit = 1000)
|
public async Task<string> ExportJsonAsync(string outputPath, int limit = 1000)
|
||||||
{
|
{
|
||||||
var rows = await _reader.ReadTrainingExamplesAsync(limit);
|
var normalizedOutputPath = RequireValue(outputPath, nameof(outputPath));
|
||||||
|
var normalizedLimit = Math.Clamp(limit, 1, 10000);
|
||||||
|
var rows = await _reader.ReadTrainingExamplesAsync(normalizedLimit);
|
||||||
var payload = new
|
var payload = new
|
||||||
{
|
{
|
||||||
formula_id = "ENGINE_HISTORY_TRAINING_DATASET_V1",
|
formula_id = "ENGINE_HISTORY_TRAINING_DATASET_V1",
|
||||||
@@ -21,9 +23,19 @@ public sealed class LearningDatasetService
|
|||||||
source = "engine_history.training_example_v1",
|
source = "engine_history.training_example_v1",
|
||||||
rows
|
rows
|
||||||
};
|
};
|
||||||
var path = Path.GetFullPath(outputPath);
|
var path = Path.GetFullPath(normalizedOutputPath);
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
|
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
|
||||||
await File.WriteAllTextAsync(path, JsonSerializer.Serialize(payload, new JsonSerializerOptions { WriteIndented = true }));
|
await File.WriteAllTextAsync(path, JsonSerializer.Serialize(payload, new JsonSerializerOptions { WriteIndented = true }));
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string RequireValue(string value, string parameterName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Value is required.", parameterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.Trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using Moq;
|
||||||
|
using QuantEngine.Application.Services;
|
||||||
|
using QuantEngine.Core.Interfaces;
|
||||||
|
|
||||||
|
namespace QuantEngine.Core.Tests;
|
||||||
|
|
||||||
|
public class LearningDatasetServiceTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task ExportJsonAsync_TrimsPathAndClampsLimit()
|
||||||
|
{
|
||||||
|
var reader = new Mock<ILearningDatasetReader>(MockBehavior.Strict);
|
||||||
|
reader.Setup(r => r.ReadTrainingExamplesAsync(10000)).ReturnsAsync([]);
|
||||||
|
|
||||||
|
var service = new LearningDatasetService(reader.Object);
|
||||||
|
var root = FindRepoRoot();
|
||||||
|
var outPath = Path.Combine(root, "Temp", "learning_dataset_test.json");
|
||||||
|
|
||||||
|
if (File.Exists(outPath))
|
||||||
|
{
|
||||||
|
File.Delete(outPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await service.ExportJsonAsync($" {outPath} ", 50000);
|
||||||
|
|
||||||
|
Assert.Equal(Path.GetFullPath(outPath), result);
|
||||||
|
Assert.True(File.Exists(result));
|
||||||
|
var text = await File.ReadAllTextAsync(result);
|
||||||
|
Assert.Contains("\"gate\": \"DATA_MISSING\"", text);
|
||||||
|
reader.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ExportJsonAsync_RejectsBlankPath()
|
||||||
|
{
|
||||||
|
var service = new LearningDatasetService(new Mock<ILearningDatasetReader>().Object);
|
||||||
|
await Assert.ThrowsAsync<ArgumentException>(() => service.ExportJsonAsync(" ", 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FindRepoRoot()
|
||||||
|
{
|
||||||
|
var current = new DirectoryInfo(AppContext.BaseDirectory);
|
||||||
|
while (current != null)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(Path.Combine(current.FullName, ".git")))
|
||||||
|
{
|
||||||
|
return current.FullName;
|
||||||
|
}
|
||||||
|
current = current.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidOperationException("Repository root not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user