1
0

SolutionSystemTests.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. using Content.Shared.Chemistry.Components;
  2. using Content.Shared.Chemistry.EntitySystems;
  3. using Content.Shared.FixedPoint;
  4. using Robust.Shared.GameObjects;
  5. using Robust.Shared.Prototypes;
  6. namespace Content.IntegrationTests.Tests.Chemistry;
  7. // We are adding two non-reactive solutions in these tests
  8. // To ensure volume(A) + volume(B) = volume(A+B)
  9. // reactions can change this assumption
  10. [TestFixture]
  11. [TestOf(typeof(SharedSolutionContainerSystem))]
  12. public sealed class SolutionSystemTests
  13. {
  14. [TestPrototypes]
  15. private const string Prototypes = @"
  16. - type: entity
  17. id: SolutionTarget
  18. components:
  19. - type: SolutionContainerManager
  20. solutions:
  21. beaker:
  22. maxVol: 50
  23. - type: reagent
  24. id: TestReagentA
  25. name: reagent-name-nothing
  26. desc: reagent-desc-nothing
  27. physicalDesc: reagent-physical-desc-nothing
  28. - type: reagent
  29. id: TestReagentB
  30. name: reagent-name-nothing
  31. desc: reagent-desc-nothing
  32. physicalDesc: reagent-physical-desc-nothing
  33. - type: reagent
  34. id: TestReagentC
  35. specificHeat: 2.0
  36. name: reagent-name-nothing
  37. desc: reagent-desc-nothing
  38. physicalDesc: reagent-physical-desc-nothing
  39. ";
  40. [Test]
  41. public async Task TryAddTwoNonReactiveReagent()
  42. {
  43. await using var pair = await PoolManager.GetServerClient();
  44. var server = pair.Server;
  45. var entityManager = server.ResolveDependency<IEntityManager>();
  46. var protoMan = server.ResolveDependency<IPrototypeManager>();
  47. var containerSystem = entityManager.System<SharedSolutionContainerSystem>();
  48. var testMap = await pair.CreateTestMap();
  49. var coordinates = testMap.GridCoords;
  50. EntityUid beaker;
  51. await server.WaitAssertion(() =>
  52. {
  53. var oilQuantity = FixedPoint2.New(15);
  54. var waterQuantity = FixedPoint2.New(10);
  55. var oilAdded = new Solution("Oil", oilQuantity);
  56. var originalWater = new Solution("Water", waterQuantity);
  57. beaker = entityManager.SpawnEntity("SolutionTarget", coordinates);
  58. Assert.That(containerSystem
  59. .TryGetSolution(beaker, "beaker", out var solutionEnt, out var solution));
  60. solution.AddSolution(originalWater, protoMan);
  61. Assert.That(containerSystem
  62. .TryAddSolution(solutionEnt.Value, oilAdded));
  63. var water = solution.GetTotalPrototypeQuantity("Water");
  64. var oil = solution.GetTotalPrototypeQuantity("Oil");
  65. Assert.Multiple(() =>
  66. {
  67. Assert.That(water, Is.EqualTo(waterQuantity));
  68. Assert.That(oil, Is.EqualTo(oilQuantity));
  69. });
  70. });
  71. await pair.CleanReturnAsync();
  72. }
  73. // This test mimics current behavior
  74. // i.e. if adding too much `TryAddSolution` adding will fail
  75. [Test]
  76. public async Task TryAddTooMuchNonReactiveReagent()
  77. {
  78. await using var pair = await PoolManager.GetServerClient();
  79. var server = pair.Server;
  80. var testMap = await pair.CreateTestMap();
  81. var entityManager = server.ResolveDependency<IEntityManager>();
  82. var protoMan = server.ResolveDependency<IPrototypeManager>();
  83. var containerSystem = entityManager.System<SharedSolutionContainerSystem>();
  84. var coordinates = testMap.GridCoords;
  85. EntityUid beaker;
  86. await server.WaitAssertion(() =>
  87. {
  88. var oilQuantity = FixedPoint2.New(1500);
  89. var waterQuantity = FixedPoint2.New(10);
  90. var oilAdded = new Solution("Oil", oilQuantity);
  91. var originalWater = new Solution("Water", waterQuantity);
  92. beaker = entityManager.SpawnEntity("SolutionTarget", coordinates);
  93. Assert.That(containerSystem
  94. .TryGetSolution(beaker, "beaker", out var solutionEnt, out var solution));
  95. solution.AddSolution(originalWater, protoMan);
  96. Assert.That(containerSystem
  97. .TryAddSolution(solutionEnt.Value, oilAdded), Is.False);
  98. var water = solution.GetTotalPrototypeQuantity("Water");
  99. var oil = solution.GetTotalPrototypeQuantity("Oil");
  100. Assert.Multiple(() =>
  101. {
  102. Assert.That(water, Is.EqualTo(waterQuantity));
  103. Assert.That(oil, Is.EqualTo(FixedPoint2.Zero));
  104. });
  105. });
  106. await pair.CleanReturnAsync();
  107. }
  108. // Unlike TryAddSolution this adds and two solution without then splits leaving only threshold in original
  109. [Test]
  110. public async Task TryMixAndOverflowTooMuchReagent()
  111. {
  112. await using var pair = await PoolManager.GetServerClient();
  113. var server = pair.Server;
  114. var entityManager = server.ResolveDependency<IEntityManager>();
  115. var protoMan = server.ResolveDependency<IPrototypeManager>();
  116. var testMap = await pair.CreateTestMap();
  117. var containerSystem = entityManager.System<SharedSolutionContainerSystem>();
  118. var coordinates = testMap.GridCoords;
  119. EntityUid beaker;
  120. await server.WaitAssertion(() =>
  121. {
  122. var ratio = 9;
  123. var threshold = 20;
  124. var waterQuantity = FixedPoint2.New(10);
  125. var oilQuantity = FixedPoint2.New(ratio * waterQuantity.Int());
  126. var oilAdded = new Solution("Oil", oilQuantity);
  127. var originalWater = new Solution("Water", waterQuantity);
  128. beaker = entityManager.SpawnEntity("SolutionTarget", coordinates);
  129. Assert.That(containerSystem
  130. .TryGetSolution(beaker, "beaker", out var solutionEnt, out var solution));
  131. solution.AddSolution(originalWater, protoMan);
  132. Assert.That(containerSystem
  133. .TryMixAndOverflow(solutionEnt.Value, oilAdded, threshold, out var overflowingSolution));
  134. Assert.Multiple(() =>
  135. {
  136. Assert.That(solution.Volume, Is.EqualTo(FixedPoint2.New(threshold)));
  137. var waterMix = solution.GetTotalPrototypeQuantity("Water");
  138. var oilMix = solution.GetTotalPrototypeQuantity("Oil");
  139. Assert.That(waterMix, Is.EqualTo(FixedPoint2.New(threshold / (ratio + 1))));
  140. Assert.That(oilMix, Is.EqualTo(FixedPoint2.New(threshold / (ratio + 1) * ratio)));
  141. Assert.That(overflowingSolution.Volume, Is.EqualTo(FixedPoint2.New(80)));
  142. var waterOverflow = overflowingSolution.GetTotalPrototypeQuantity("Water");
  143. var oilOverFlow = overflowingSolution.GetTotalPrototypeQuantity("Oil");
  144. Assert.That(waterOverflow, Is.EqualTo(waterQuantity - waterMix));
  145. Assert.That(oilOverFlow, Is.EqualTo(oilQuantity - oilMix));
  146. });
  147. });
  148. await pair.CleanReturnAsync();
  149. }
  150. // TryMixAndOverflow will fail if Threshold larger than MaxVolume
  151. [Test]
  152. public async Task TryMixAndOverflowTooBigOverflow()
  153. {
  154. await using var pair = await PoolManager.GetServerClient();
  155. var server = pair.Server;
  156. var entityManager = server.ResolveDependency<IEntityManager>();
  157. var protoMan = server.ResolveDependency<IPrototypeManager>();
  158. var containerSystem = entityManager.System<SharedSolutionContainerSystem>();
  159. var testMap = await pair.CreateTestMap();
  160. var coordinates = testMap.GridCoords;
  161. EntityUid beaker;
  162. await server.WaitAssertion(() =>
  163. {
  164. var ratio = 9;
  165. var threshold = 60;
  166. var waterQuantity = FixedPoint2.New(10);
  167. var oilQuantity = FixedPoint2.New(ratio * waterQuantity.Int());
  168. var oilAdded = new Solution("Oil", oilQuantity);
  169. var originalWater = new Solution("Water", waterQuantity);
  170. beaker = entityManager.SpawnEntity("SolutionTarget", coordinates);
  171. Assert.That(containerSystem
  172. .TryGetSolution(beaker, "beaker", out var solutionEnt, out var solution));
  173. solution.AddSolution(originalWater, protoMan);
  174. Assert.That(containerSystem
  175. .TryMixAndOverflow(solutionEnt.Value, oilAdded, threshold, out _),
  176. Is.False);
  177. });
  178. await pair.CleanReturnAsync();
  179. }
  180. [Test]
  181. public async Task TestTemperatureCalculations()
  182. {
  183. await using var pair = await PoolManager.GetServerClient();
  184. var server = pair.Server;
  185. var protoMan = server.ResolveDependency<IPrototypeManager>();
  186. const float temp = 100.0f;
  187. // Adding reagent with adjusts temperature
  188. await server.WaitAssertion(() =>
  189. {
  190. var solution = new Solution("TestReagentA", FixedPoint2.New(100)) { Temperature = temp };
  191. Assert.That(solution.Temperature, Is.EqualTo(temp * 1));
  192. solution.AddSolution(new Solution("TestReagentA", FixedPoint2.New(100)) { Temperature = temp * 3 }, protoMan);
  193. Assert.That(solution.Temperature, Is.EqualTo(temp * 2));
  194. solution.AddSolution(new Solution("TestReagentB", FixedPoint2.New(100)) { Temperature = temp * 5 }, protoMan);
  195. Assert.That(solution.Temperature, Is.EqualTo(temp * 3));
  196. });
  197. // adding solutions combines thermal energy
  198. await server.WaitAssertion(() =>
  199. {
  200. var solutionOne = new Solution("TestReagentA", FixedPoint2.New(100)) { Temperature = temp };
  201. var solutionTwo = new Solution("TestReagentB", FixedPoint2.New(100)) { Temperature = temp };
  202. solutionTwo.AddReagent("TestReagentC", FixedPoint2.New(100));
  203. var thermalEnergyOne = solutionOne.GetHeatCapacity(protoMan) * solutionOne.Temperature;
  204. var thermalEnergyTwo = solutionTwo.GetHeatCapacity(protoMan) * solutionTwo.Temperature;
  205. solutionOne.AddSolution(solutionTwo, protoMan);
  206. Assert.That(solutionOne.GetHeatCapacity(protoMan) * solutionOne.Temperature, Is.EqualTo(thermalEnergyOne + thermalEnergyTwo));
  207. });
  208. await pair.CleanReturnAsync();
  209. }
  210. }