namespace AyCode.Core.Tests.TestModels; /// /// Factory for creating test data hierarchies. /// Used by both unit tests and benchmarks. /// /// All placeholder strings use Hungarian (UTF-8 multi-byte) content to exercise the UTF-8 /// encoder/decoder path rather than the ASCII fast-path. This makes the benchmark reflect /// realistic i18n payloads, not just the FixStrAscii / StringAscii marker fast-paths. /// public static class TestDataFactory { private static int _idCounter = 1; /// /// Reset the ID counter (call in test setup) /// public static void ResetIdCounter() => _idCounter = 1; /// /// Get the next unique ID /// public static int NextId() => _idCounter++; #region Simple Object Creation /// /// Create a shared tag for cross-reference testing /// public static SharedTag CreateTag(string? name = null, string? color = null) { var id = _idCounter++; return new SharedTag { Id = id, Name = name ?? $"Címke-{id}", Color = color ?? $"Szín-#{id:X2}{(id * 10) % 256:X2}{(id * 20) % 256:X2}", Priority = id % 5, IsActive = id % 2 == 0, CreatedAt = DateTime.UtcNow.AddDays(-id), Description = $"Címke leírása {id}" }; } /// /// Create a shared category /// public static SharedCategory CreateCategory(string? name = null, int? parentId = null) { var id = _idCounter++; return new SharedCategory { Id = id, Name = name ?? $"Kategória-{id}", Description = $"Kategória leírása {id}", SortOrder = id * 100, IsDefault = id == 1, ParentCategoryId = parentId, CreatedAt = DateTime.UtcNow.AddMonths(-id), UpdatedAt = DateTime.UtcNow.AddDays(-id) }; } /// /// Create a shared user for cross-reference testing /// public static SharedUser CreateUser(string? username = null, TestUserRole role = TestUserRole.User) { var id = _idCounter++; return new SharedUser { Id = id, Username = username ?? $"felhasználó{id}", Email = $"felhasználó{id}@teszt.hu", FirstName = $"Vezetéknév{id}", LastName = $"Keresztnév{id}", IsActive = true, Role = role, LastLoginAt = DateTime.UtcNow.AddHours(-id), CreatedAt = DateTime.UtcNow.AddYears(-1), Preferences = new UserPreferences { Theme = id % 2 == 0 ? "sötét" : "világos", Language = "magyar", NotificationsEnabled = true, EmailDigestFrequency = "naponkénti" } }; } /// /// Create metadata info (non-IId) /// public static MetadataInfo CreateMetadata(string? key = null, bool withChild = false) { var id = _idCounter++; return new MetadataInfo { Key = key ?? $"Metaadat-{id}", Value = $"MetaÉrték-{id}", Timestamp = DateTime.UtcNow.AddMinutes(-id * 10), ChildMetadata = withChild ? CreateMetadata($"Gyermek-{id}", false) : null }; } #endregion #region Hierarchy Creation (5 Levels) /// /// Create a deep order hierarchy with configurable depth. /// Supports both IId-based (SharedTag, SharedUser, SharedCategory) and Non-IId (UserPreferences) shared references. /// public static TestOrder CreateOrder( int itemCount = 2, int palletsPerItem = 2, int measurementsPerPallet = 2, int pointsPerMeasurement = 3, SharedTag? sharedTag = null, SharedUser? sharedUser = null, MetadataInfo? sharedMetadata = null, UserPreferences? sharedPreferences = null, SharedCategory? sharedCategory = null) { // If sharedUser is provided but no sharedPreferences, use the user's preferences as shared sharedPreferences ??= sharedUser?.Preferences; var order = new TestOrder { Id = _idCounter++, OrderNumber = $"Megrendelés-{_idCounter:D4}", Status = TestStatus.Pending, CreatedAt = DateTime.UtcNow, TotalAmount = 1000m + _idCounter * 100, PrimaryTag = sharedTag, SecondaryTag = sharedTag, // Same reference for $ref testing Owner = sharedUser, Category = sharedCategory, OrderMetadata = sharedMetadata, AuditMetadata = sharedMetadata // Same reference for Newtonsoft $ref }; if (sharedTag != null) { order.Tags.Add(sharedTag); } for (int i = 0; i < itemCount; i++) { var item = CreateOrderItem( palletsPerItem, measurementsPerPallet, pointsPerMeasurement, sharedTag, sharedUser, sharedMetadata, sharedPreferences, sharedCategory); item.ParentOrder = order; order.Items.Add(item); } return order; } /// /// Create an order item with pallets. /// Supports both IId-based and Non-IId shared references. /// public static TestOrderItem CreateOrderItem( int palletCount = 2, int measurementsPerPallet = 2, int pointsPerMeasurement = 3, SharedTag? sharedTag = null, SharedUser? sharedUser = null, MetadataInfo? sharedMetadata = null, UserPreferences? sharedPreferences = null, SharedCategory? sharedCategory = null) { // Create assignee - if sharedUser provided, use it. Otherwise create new user with sharedPreferences SharedUser? assignee = sharedUser; if (assignee == null && sharedPreferences != null) { // Create a new user but with shared preferences (Non-IId ref testing) assignee = CreateUser(); assignee.Preferences = sharedPreferences; } var item = new TestOrderItem { Id = _idCounter++, ProductName = $"Termék-{_idCounter}", Quantity = 10 + _idCounter, UnitPrice = 5.5m * _idCounter, Status = TestStatus.Pending, Tag = sharedTag, Assignee = assignee, ItemMetadata = sharedMetadata }; for (int i = 0; i < palletCount; i++) { // Pass shared references to all levels - creates many shared refs! var pallet = CreatePallet( measurementsPerPallet, pointsPerMeasurement, sharedMetadata, sharedTag, // IId shared ref sharedUser, // IId shared ref sharedCategory); // IId shared ref pallet.ParentItem = item; item.Pallets.Add(pallet); } return item; } /// /// Create a pallet with measurements /// public static TestPallet CreatePallet( int measurementCount = 2, int pointsPerMeasurement = 3, MetadataInfo? sharedMetadata = null, SharedTag? sharedTag = null, SharedUser? sharedInspector = null, SharedCategory? sharedCategory = null) { var pallet = new TestPallet { Id = _idCounter++, PalletCode = $"Raklapkód-{_idCounter:D4}", TrayCount = 5 + _idCounter % 10, Status = TestStatus.Pending, Weight = 100.5 + _idCounter, PalletMetadata = sharedMetadata, Tag = sharedTag, Inspector = sharedInspector, Category = sharedCategory }; for (int i = 0; i < measurementCount; i++) { var measurement = CreateMeasurement(pointsPerMeasurement, sharedTag, sharedInspector); measurement.ParentPallet = pallet; pallet.Measurements.Add(measurement); } return pallet; } /// /// Create a measurement with points /// public static TestMeasurement CreateMeasurement( int pointCount = 3, SharedTag? sharedTag = null, SharedUser? sharedOperator = null) { var measurement = new TestMeasurement { Id = _idCounter++, Name = $"Mérés-{_idCounter}", TotalWeight = 100.5 + _idCounter, CreatedAt = DateTime.UtcNow, Tag = sharedTag, Operator = sharedOperator }; for (int i = 0; i < pointCount; i++) { var point = CreateMeasurementPoint(sharedTag, sharedOperator); point.ParentMeasurement = measurement; measurement.Points.Add(point); } return measurement; } /// /// Create a measurement point /// public static TestMeasurementPoint CreateMeasurementPoint( SharedTag? sharedTag = null, SharedUser? sharedVerifier = null) { var id = _idCounter++; return new TestMeasurementPoint { Id = id, Label = $"MérőPont-{id}", Value = 10.5 + (id * 0.1), MeasuredAt = DateTime.UtcNow, Tag = sharedTag, Verifier = sharedVerifier }; } #endregion #region Benchmark Data Generation /// /// Create a large graph for benchmarking with many cross-references. /// Creates approximately (itemCount * palletsPerItem * measurementsPerPallet * pointsPerMeasurement) objects. /// public static TestOrder CreateBenchmarkOrder( int itemCount = 5, int palletsPerItem = 4, int measurementsPerPallet = 3, int pointsPerMeasurement = 5) { ResetIdCounter(); // Create shared references that will be used throughout var sharedTags = Enumerable.Range(1, 10).Select(_ => CreateTag()).ToList(); var sharedUser = CreateUser("mérőfelhasználó", TestUserRole.Admin); var sharedMetadata = CreateMetadata("mérőteszt", withChild: true); var order = new TestOrder { Id = _idCounter++, OrderNumber = $"MÉRŐTESZT-{_idCounter:D6}", Status = TestStatus.Processing, CreatedAt = DateTime.UtcNow, TotalAmount = 999999.99m, PrimaryTag = sharedTags[0], SecondaryTag = sharedTags[0], Owner = sharedUser, Category = CreateCategory("Mérőteszt"), OrderMetadata = sharedMetadata, AuditMetadata = sharedMetadata, Tags = sharedTags.Take(3).ToList() }; for (int i = 0; i < itemCount; i++) { var item = new TestOrderItem { Id = _idCounter++, ProductName = $"MérőTermék-{i}", Quantity = 100 + i * 10, UnitPrice = 25.99m + i, Status = (TestStatus)(i % 5), Tag = sharedTags[i % sharedTags.Count], Assignee = sharedUser, ItemMetadata = sharedMetadata }; item.ParentOrder = order; for (int p = 0; p < palletsPerItem; p++) { var pallet = new TestPallet { Id = _idCounter++, PalletCode = $"Raklapkód-{i}-{p}", TrayCount = 10 + p, Status = (TestStatus)(p % 4), Weight = 500.0 + p * 50, PalletMetadata = sharedMetadata }; pallet.ParentItem = item; for (int m = 0; m < measurementsPerPallet; m++) { var measurement = new TestMeasurement { Id = _idCounter++, Name = $"Mérés-{i}-{p}-{m}", TotalWeight = 50.0 + m * 10, CreatedAt = DateTime.UtcNow.AddMinutes(-m) }; measurement.ParentPallet = pallet; for (int pt = 0; pt < pointsPerMeasurement; pt++) { var point = new TestMeasurementPoint { Id = _idCounter++, Label = $"MérőPnt-{i}-{p}-{m}-{pt}", Value = 1.0 + pt * 0.5, MeasuredAt = DateTime.UtcNow.AddSeconds(-pt) }; point.ParentMeasurement = measurement; measurement.Points.Add(point); } pallet.Measurements.Add(measurement); } item.Pallets.Add(pallet); } order.Items.Add(item); } return order; } /// /// Create a large-scale benchmark order similar to production workloads. /// Targets ~50,000-100,000+ IId objects with deep hierarchy and shared references. /// /// Number of root items (default 500 for ~50K objects, use 2200 for production-like) /// Pallets per item /// Measurements per pallet /// Points per measurement /// Large TestOrder with many IId references public static TestOrder CreateLargeScaleBenchmarkOrder( int rootItemCount = 500, int palletsPerItem = 3, int measurementsPerPallet = 3, int pointsPerMeasurement = 4) { ResetIdCounter(); // Create shared references - these will be heavily reused (tests $ref handling) var sharedTags = Enumerable.Range(1, 50).Select(_ => CreateTag()).ToList(); var sharedUsers = Enumerable.Range(1, 20).Select(i => CreateUser($"felhasználó{i}", (TestUserRole)(i % 4))).ToList(); var sharedMetadata = CreateMetadata("nagy-méretű", withChild: true); var sharedCategories = Enumerable.Range(1, 10).Select(i => CreateCategory($"Kategória-{i}")).ToList(); var order = new TestOrder { Id = _idCounter++, OrderNumber = $"NAGYMÉRET-{_idCounter:D8}", Status = TestStatus.Processing, CreatedAt = DateTime.UtcNow, TotalAmount = 9999999.99m, PrimaryTag = sharedTags[0], SecondaryTag = sharedTags[0], // Same ref Owner = sharedUsers[0], Category = sharedCategories[0], OrderMetadata = sharedMetadata, AuditMetadata = sharedMetadata, // Same ref Tags = sharedTags.Take(5).ToList() }; for (int i = 0; i < rootItemCount; i++) { var item = new TestOrderItem { Id = _idCounter++, ProductName = $"Termék-{i}", Quantity = 100 + i, UnitPrice = 10.99m + (i % 100), Status = (TestStatus)(i % 5), Tag = sharedTags[i % sharedTags.Count], // Shared ref Assignee = sharedUsers[i % sharedUsers.Count], // Shared ref ItemMetadata = sharedMetadata // Shared ref }; item.ParentOrder = order; for (int p = 0; p < palletsPerItem; p++) { var pallet = new TestPallet { Id = _idCounter++, PalletCode = $"Raklapkód-{i}-{p}", TrayCount = 5 + (p % 10), Status = (TestStatus)(p % 4), Weight = 100.0 + p * 10, PalletMetadata = sharedMetadata // Shared ref }; pallet.ParentItem = item; for (int m = 0; m < measurementsPerPallet; m++) { var measurement = new TestMeasurement { Id = _idCounter++, Name = $"Mérés-{i}-{p}-{m}", TotalWeight = 10.0 + m, CreatedAt = DateTime.UtcNow }; measurement.ParentPallet = pallet; for (int pt = 0; pt < pointsPerMeasurement; pt++) { var point = new TestMeasurementPoint { Id = _idCounter++, Label = $"MérőPnt-{i}-{p}-{m}-{pt}", Value = pt * 0.1, MeasuredAt = DateTime.UtcNow }; point.ParentMeasurement = measurement; measurement.Points.Add(point); } pallet.Measurements.Add(measurement); } item.Pallets.Add(pallet); } order.Items.Add(item); } return order; } /// /// Calculate approximate object count for large-scale benchmark. /// public static int CalculateObjectCount(int rootItems, int pallets, int measurements, int points) { // 1 order + rootItems + (rootItems * pallets) + (rootItems * pallets * measurements) + (rootItems * pallets * measurements * points) // Plus shared objects (tags, users, metadata, categories) var sharedObjects = 50 + 20 + 2 + 10; // tags + users + metadata + categories var hierarchyObjects = 1 + rootItems + (rootItems * pallets) + (rootItems * pallets * measurements) + (rootItems * pallets * measurements * points); return sharedObjects + hierarchyObjects; } /// /// Create primitive test data for all-types testing /// public static PrimitiveTestClass CreatePrimitiveTestData() { return new PrimitiveTestClass { IntValue = int.MaxValue, LongValue = long.MaxValue, DoubleValue = 3.14159265358979, DecimalValue = 12345.6789m, FloatValue = 1.5f, BoolValue = true, StringValue = "Teszt Szöveg árvíztűrőtükörfúrógép", GuidValue = Guid.Parse("12345678-1234-1234-1234-123456789abc"), DateTimeValue = new DateTime(2024, 12, 25, 12, 30, 45, DateTimeKind.Utc), EnumValue = TestStatus.Shipped, ByteValue = 255, ShortValue = short.MaxValue, NullableInt = 42, NullableIntNull = null }; } #endregion }