Refactor products and buildings to support modding

This commit is contained in:
sokol
2026-02-20 21:51:06 +03:00
parent f320aa50ed
commit ec3da03bba
12 changed files with 1109 additions and 115 deletions

View File

@@ -0,0 +1,81 @@
using MyBiz.Core;
namespace MyBiz.Tests;
public class BuildingTests
{
[Fact]
public void Building_CalculateEfficiency_FullWorkers_ShouldBeMax()
{
// Arrange
var config = new BuildingTypeConfig
{
Id = "factory",
BaseEfficiency = 100,
WorkerSlots = 10
};
var building = new Building
{
TypeConfig = config,
Workers = 10,
Level = 1
};
// Act
building.CalculateEfficiency();
// Assert
Assert.Equal(100, building.CurrentEfficiency);
}
[Fact]
public void Building_CalculateEfficiency_NoWorkers_ShouldBeZero()
{
// Arrange
var config = new BuildingTypeConfig
{
Id = "factory",
BaseEfficiency = 100,
WorkerSlots = 10
};
var building = new Building
{
TypeConfig = config,
Workers = 0,
Level = 1
};
// Act
building.CalculateEfficiency();
// Assert
Assert.Equal(0, building.CurrentEfficiency);
}
[Fact]
public void Building_LevelBonus_ShouldIncreaseEfficiency()
{
// Arrange
var config = new BuildingTypeConfig
{
Id = "factory",
BaseEfficiency = 100,
WorkerSlots = 10
};
var building = new Building
{
TypeConfig = config,
Workers = 10,
Level = 5
};
// Act
building.CalculateEfficiency();
// Assert
Assert.Equal(120, building.CurrentEfficiency); // 100 + (4 * 5)
}
}

View File

@@ -0,0 +1,67 @@
using MyBiz.Core;
namespace MyBiz.Tests;
public class DefaultProductsTests
{
[Fact]
public void DefaultProducts_GetAll_ShouldReturn12Products()
{
// Act
var products = DefaultProducts.GetAll().ToList();
// Assert
Assert.Equal(12, products.Count);
}
[Fact]
public void DefaultProducts_ShouldHaveAllCategories()
{
// Act
var products = DefaultProducts.GetAll().ToList();
// Assert
Assert.Contains(products, p => p.Category == ProductCategory.RawMaterial);
Assert.Contains(products, p => p.Category == ProductCategory.Component);
Assert.Contains(products, p => p.Category == ProductCategory.ConsumerGoods);
}
[Fact]
public void DefaultProducts_RegisterAll_ShouldAddToRegistry()
{
// Arrange
var registry = new ProductRegistry();
// Act
DefaultProducts.RegisterAll(registry);
// Assert
Assert.Equal(12, registry.Count);
Assert.NotNull(registry.GetById("goods_food"));
Assert.NotNull(registry.GetById("goods_automobile"));
}
[Fact]
public void DefaultProducts_Automobile_ShouldHaveCorrectProperties()
{
// Act
var automobile = DefaultProducts.GetAll().First(p => p.Id == "goods_automobile");
// Assert
Assert.Equal("Автомобили", automobile.Name);
Assert.Equal(5000m, automobile.BasePrice);
Assert.Equal(1920, automobile.AvailableFromYear);
Assert.False(automobile.IsPerishable);
}
[Fact]
public void DefaultProducts_Food_ShouldBePerishable()
{
// Act
var food = DefaultProducts.GetAll().First(p => p.Id == "goods_food");
// Assert
Assert.True(food.IsPerishable);
Assert.Equal(5, food.ShelfLife);
}
}

View File

@@ -2,40 +2,192 @@ using MyBiz.Core;
namespace MyBiz.Tests;
public class ProductTests
public class ProductTypeTests
{
[Fact]
public void Product_Creation_ShouldInitializeProperties()
public void ProductType_Creation_ShouldInitializeProperties()
{
// Arrange & Act
var product = new Product
var productType = new ProductType
{
Type = ProductType.Food,
Id = "food_bread",
Name = "Bread",
Description = "Fresh baked bread",
Category = ProductCategory.ConsumerGoods,
BasePrice = 10m
BasePrice = 10m,
BaseDemand = 100,
AvailableFromYear = 1950
};
// Assert
Assert.Equal(ProductType.Food, product.Type);
Assert.Equal("Bread", product.Name);
Assert.Equal(ProductCategory.ConsumerGoods, product.Category);
Assert.Equal(10m, product.BasePrice);
Assert.Equal("food_bread", productType.Id);
Assert.Equal("Bread", productType.Name);
Assert.Equal(ProductCategory.ConsumerGoods, productType.Category);
Assert.Equal(10m, productType.BasePrice);
Assert.Equal(1950, productType.AvailableFromYear);
Assert.False(productType.IsPerishable);
}
[Fact]
public void Product_CurrentPrice_ShouldDefaultToBasePrice()
public void ProductType_Clone_ShouldCreateIndependentCopy()
{
// Arrange
var original = new ProductType
{
Id = "test",
Name = "Test Product",
BasePrice = 50m
};
original.RequiredTechnologies.Add("tech1");
// Act
var clone = original.Clone();
clone.Name = "Modified";
clone.RequiredTechnologies.Add("tech2");
// Assert
Assert.Equal("Test Product", original.Name);
Assert.Equal("Modified", clone.Name);
Assert.Single(original.RequiredTechnologies);
Assert.Equal(2, clone.RequiredTechnologies.Count);
}
}
public class ProductTests
{
[Fact]
public void Product_Add_ShouldIncreaseQuantity()
{
// Arrange
var product = new Product
{
BasePrice = 25m
Type = new ProductType { Id = "test", BasePrice = 10m },
Quantity = 5
};
// Act
product.CurrentPrice = product.BasePrice;
product.Add(10);
// Assert
Assert.Equal(25m, product.CurrentPrice);
Assert.Equal(15, product.Quantity);
}
[Fact]
public void Product_Remove_ShouldDecreaseQuantity()
{
// Arrange
var product = new Product
{
Type = new ProductType { Id = "test", BasePrice = 10m },
Quantity = 20
};
// Act
var removed = product.Remove(15);
// Assert
Assert.Equal(15, removed);
Assert.Equal(5, product.Quantity);
}
[Fact]
public void Product_Remove_MoreThanAvailable_ShouldRemoveAll()
{
// Arrange
var product = new Product
{
Type = new ProductType { Id = "test", BasePrice = 10m },
Quantity = 10
};
// Act
var removed = product.Remove(50);
// Assert
Assert.Equal(10, removed);
Assert.Equal(0, product.Quantity);
Assert.True(product.IsSpoiled);
}
[Fact]
public void Product_Perishable_ShouldSpoilAfterShelfLife()
{
// Arrange
var product = new Product
{
Type = new ProductType { Id = "food", BasePrice = 10m, ShelfLife = 5 },
Quantity = 10,
CreatedAtTick = 0
};
// Act
product.Update(6); // 6 ticks later
// Assert
Assert.True(product.IsSpoiled);
Assert.False(product.IsUsable);
}
}
public class ProductRegistryTests
{
[Fact]
public void Registry_Register_ShouldAddProductType()
{
// Arrange
var registry = new ProductRegistry();
var productType = new ProductType { Id = "test", Name = "Test" };
// Act
registry.Register(productType);
// Assert
Assert.Equal(1, registry.Count);
Assert.Same(productType, registry.GetById("test"));
}
[Fact]
public void Registry_GetById_UnknownId_ShouldReturnNull()
{
// Arrange
var registry = new ProductRegistry();
// Act
var result = registry.GetById("unknown");
// Assert
Assert.Null(result);
}
[Fact]
public void Registry_GetByCategory_ShouldFilterProducts()
{
// Arrange
var registry = new ProductRegistry();
registry.Register(new ProductType { Id = "raw1", Category = ProductCategory.RawMaterial });
registry.Register(new ProductType { Id = "raw2", Category = ProductCategory.RawMaterial });
registry.Register(new ProductType { Id = "consumer1", Category = ProductCategory.ConsumerGoods });
// Act
var rawMaterials = registry.GetByCategory(ProductCategory.RawMaterial);
// Assert
Assert.Equal(2, rawMaterials.Count());
}
[Fact]
public void Registry_GetAvailableInYear_ShouldFilterByYear()
{
// Arrange
var registry = new ProductRegistry();
registry.Register(new ProductType { Id = "old", AvailableFromYear = 1950 });
registry.Register(new ProductType { Id = "new", AvailableFromYear = 2000 });
// Act
var availableIn1970 = registry.GetAvailableInYear(1970);
// Assert
Assert.Single(availableIn1970);
Assert.Equal("old", availableIn1970.First().Id);
}
}