Refactor products and buildings to support modding
This commit is contained in:
81
backend/tests/MyBiz.Tests/BuildingTests.cs
Normal file
81
backend/tests/MyBiz.Tests/BuildingTests.cs
Normal 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)
|
||||
}
|
||||
}
|
||||
67
backend/tests/MyBiz.Tests/DefaultProductsTests.cs
Normal file
67
backend/tests/MyBiz.Tests/DefaultProductsTests.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user