mirror of
https://github.com/dotnet/skills.git
synced 2026-09-20 09:49:54 +08:00
948a9a52ef
* Add exp-mock-usage-analysis skill and evaluation New experimental skill that detects unused, redundant, or unnecessary mocks in .NET test suites. Covers Moq, NSubstitute, FakeItEasy, and manual test doubles. - SKILL.md with 6-step workflow: gather code, classify mocks, detect anti-patterns, incorporate runtime data, generate recommendations, report findings - eval.yaml with 10 scenarios: trivial type mocking, unused setups, redundant configs, stable utility mocks, well-placed mocks (no false positives), NSubstitute support, FakeItEasy support, setup sprawl, and 2 non-activation boundary tests - Fixture files for each scenario with production + test code - CODEOWNERS entry for @dotnet/dotnet-testing * Remove no-headroom scenarios, increase NSubstitute timeout Remove 4 scenarios where baseline already scores 5.0/5 (model handles these well without skill guidance): - Detect mocking of DTOs, records, and enums - Recognize well-placed mocks without inventing false positives - Decline when asked about non-mock test anti-patterns - Decline mock framework migration request Increase NSubstitute scenario timeout from 120s to 180s to avoid baseline timeouts impacting scoring. Remaining 6 scenarios all show positive skill impact (3→5, 3→4, etc). * Document areas the model handles well without the skill Add a subsection under 'When Not to Use' listing mock-related tasks where the base model already scores 5.0/5 without skill guidance: - Mocking trivial types (DTOs, records, enums) - Recognizing well-placed mocks (no false positives) * Fix md * Improve
84 lines
2.6 KiB
C#
84 lines
2.6 KiB
C#
using Microsoft.Extensions.Logging;
|
|
|
|
namespace ReportGen;
|
|
|
|
public interface IDataSource
|
|
{
|
|
IReadOnlyList<SalesRecord> GetSalesData(DateTime from, DateTime to);
|
|
IReadOnlyList<CustomerRecord> GetCustomers();
|
|
IReadOnlyList<ProductRecord> GetProducts();
|
|
decimal GetExchangeRate(string fromCurrency, string toCurrency);
|
|
}
|
|
|
|
public interface IReportFormatter
|
|
{
|
|
string FormatAsHtml(ReportData data);
|
|
string FormatAsPdf(ReportData data);
|
|
string FormatAsCsv(ReportData data);
|
|
}
|
|
|
|
public interface IReportStorage
|
|
{
|
|
string Save(string reportName, string content, string format);
|
|
string? GetLatest(string reportName);
|
|
}
|
|
|
|
public interface ICacheService
|
|
{
|
|
T? Get<T>(string key);
|
|
void Set<T>(string key, T value, TimeSpan expiry);
|
|
void Invalidate(string key);
|
|
}
|
|
|
|
public record SalesRecord(string ProductId, decimal Amount, string Currency, DateTime Date);
|
|
public record CustomerRecord(int Id, string Name, string Region);
|
|
public record ProductRecord(string Id, string Name, string Category, decimal Price);
|
|
public record ReportData(string Title, IReadOnlyList<ReportRow> Rows, decimal Total);
|
|
public record ReportRow(string Label, decimal Value);
|
|
|
|
public class ReportGenerator
|
|
{
|
|
private readonly IDataSource _dataSource;
|
|
private readonly IReportFormatter _formatter;
|
|
private readonly IReportStorage _storage;
|
|
private readonly ICacheService _cache;
|
|
private readonly ILogger<ReportGenerator> _logger;
|
|
|
|
public ReportGenerator(
|
|
IDataSource dataSource,
|
|
IReportFormatter formatter,
|
|
IReportStorage storage,
|
|
ICacheService cache,
|
|
ILogger<ReportGenerator> logger)
|
|
{
|
|
_dataSource = dataSource;
|
|
_formatter = formatter;
|
|
_storage = storage;
|
|
_cache = cache;
|
|
_logger = logger;
|
|
}
|
|
|
|
public string GenerateSalesReport(DateTime from, DateTime to, string format)
|
|
{
|
|
var sales = _dataSource.GetSalesData(from, to);
|
|
var rows = sales
|
|
.GroupBy(s => s.ProductId)
|
|
.Select(g => new ReportRow(g.Key, g.Sum(s => s.Amount)))
|
|
.ToList();
|
|
|
|
var data = new ReportData("Sales Report", rows, rows.Sum(r => r.Value));
|
|
|
|
var content = format switch
|
|
{
|
|
"html" => _formatter.FormatAsHtml(data),
|
|
"pdf" => _formatter.FormatAsPdf(data),
|
|
"csv" => _formatter.FormatAsCsv(data),
|
|
_ => throw new ArgumentException($"Unknown format: {format}")
|
|
};
|
|
|
|
var reportId = _storage.Save($"sales-{from:yyyyMMdd}-{to:yyyyMMdd}", content, format);
|
|
_logger.LogInformation("Generated sales report {ReportId}", reportId);
|
|
return reportId;
|
|
}
|
|
}
|