From bf2f0b161a43f17f7e56646b939eadbcd3e37b25 Mon Sep 17 00:00:00 2001 From: Piotr Jazdzyk Date: Sun, 1 Sep 2024 19:44:54 +0200 Subject: [PATCH] SNSUNI-101: Add SupportedQuantitiesRegistry, add toUnit() method which accepts unit symbol as String. --- README.md | 14 +- pom.xml | 20 +-- .../unitsystem/PhysicalQuantity.java | 10 ++ .../unitility/unitsystem/common/Angle.java | 7 +- .../unitility/unitsystem/common/Area.java | 6 + .../unitility/unitsystem/common/Distance.java | 6 + .../unitility/unitsystem/common/Mass.java | 10 +- .../unitility/unitsystem/common/Velocity.java | 6 + .../unitility/unitsystem/common/Volume.java | 6 + .../dimensionless/BypassFactor.java | 5 + .../dimensionless/GrashofNumber.java | 5 + .../dimensionless/PrandtlNumber.java | 5 + .../dimensionless/ReynoldsNumber.java | 5 + .../unitility/unitsystem/flow/MassFlow.java | 6 + .../unitsystem/flow/VolumetricFlow.java | 6 + .../unitsystem/geographic/GeoDistance.java | 6 + .../unitsystem/geographic/Latitude.java | 6 + .../unitsystem/geographic/Longitude.java | 6 + .../unitsystem/humidity/HumidityRatio.java | 6 + .../unitsystem/humidity/RelativeHumidity.java | 6 + .../unitsystem/mechanical/Force.java | 6 + .../unitsystem/mechanical/Momentum.java | 6 + .../unitsystem/mechanical/Torque.java | 6 + .../unitsystem/thermodynamic/Density.java | 6 + .../thermodynamic/DynamicViscosity.java | 6 + .../unitsystem/thermodynamic/Energy.java | 6 + .../thermodynamic/KinematicViscosity.java | 6 + .../unitsystem/thermodynamic/Power.java | 6 + .../unitsystem/thermodynamic/Pressure.java | 6 + .../thermodynamic/SpecificEnthalpy.java | 6 + .../thermodynamic/SpecificHeat.java | 6 + .../unitsystem/thermodynamic/Temperature.java | 6 + .../thermodynamic/ThermalConductivity.java | 6 + .../thermodynamic/ThermalDiffusivity.java | 6 + .../unitsystem/util/PhysicalQuantityInfo.java | 8 + .../unitsystem/util/PhysicalUnitInfo.java | 7 + .../unitsystem/util/StringTransformer.java | 1 + .../util/SupportedQuantitiesRegistry.java | 151 ++++++++++++++++++ .../unitsystem/PhysicalQuantityTest.java | 19 ++- .../unitsystem/customunit/CustomAngle.java | 6 + .../PhysicalQuantityParsingFactoryTest.java | 7 +- .../util/SupportedQuantitiesRegistryTest.java | 61 +++++++ 42 files changed, 469 insertions(+), 22 deletions(-) create mode 100644 unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityInfo.java create mode 100644 unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalUnitInfo.java create mode 100644 unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/SupportedQuantitiesRegistry.java create mode 100644 unitility-core/src/test/java/com/synerset/unitility/unitsystem/util/SupportedQuantitiesRegistryTest.java diff --git a/README.md b/README.md index 4cfaf69..9512317 100644 --- a/README.md +++ b/README.md @@ -61,13 +61,13 @@ features, such as overloaded operators. Copy the Maven dependency provided below to your pom.xml file, and you are ready to go. For other package managers, check maven central repository: -[UNITILITY](https://search.maven.org/artifact/com.synerset/unitility/2.4.1/jar?eh=). +[UNITILITY](https://search.maven.org/artifact/com.synerset/unitility/2.4.2/jar?eh=). ```xml com.synerset unitility-core - 2.4.1 + 2.4.2 ``` If you use frameworks to develop web applications, it is recommended to use Unitility extension modules, @@ -79,7 +79,7 @@ Extension for the Spring Boot framework: com.synerset unitility-spring - 2.4.1 + 2.4.2 ``` Extension for the Quarkus framework: @@ -87,7 +87,7 @@ Extension for the Quarkus framework: com.synerset unitility-quarkus - 2.4.1 + 2.4.2 ``` Extensions include CORE module, so you don't have to put it separate in your pom. @@ -481,7 +481,7 @@ deserialization back to Java objects. To include this module in your project, us com.synerset unitility-jackson - 2.4.1 + 2.4.2 ``` PhysicalQuantity JSON structure for valid serialization / deserialization has been defined as in the following example: @@ -506,7 +506,7 @@ add the following dependency: com.synerset unitility-spring - 2.4.1 + 2.4.2 ``` Adding Spring module to the project will automatically: @@ -546,7 +546,7 @@ add following dependency: com.synerset unitility-quarkus - 2.4.1 + 2.4.2 ``` Adding Quarkus module to the project will automatically: diff --git a/pom.xml b/pom.xml index cb2e0fd..8a93ff6 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ - 2.4.1 + 2.4.2 17 @@ -52,28 +52,28 @@ UTF-8 - 2.17.1 + 2.17.2 - 3.3.0 + 3.3.3 - 3.11.0 + 3.14.1 3.1.0 - 6.0.0 + 6.0.1 8.0.1.Final 0.8.12 - 5.10.2 - 3.25.3 + 5.11.0 + 3.26.3 1.6.0 - 3.6.3 + 3.10.0 3.3.1 1.6.13 - 3.2.5 - 3.1.8 + 3.5.0 + 3.2.2 synerset diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/PhysicalQuantity.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/PhysicalQuantity.java index b35d119..54ce3f2 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/PhysicalQuantity.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/PhysicalQuantity.java @@ -1,5 +1,6 @@ package com.synerset.unitility.unitsystem; +import com.synerset.unitility.unitsystem.exceptions.UnitSystemParseException; import com.synerset.unitility.unitsystem.util.ValueFormatter; import java.util.Objects; @@ -55,6 +56,15 @@ public interface PhysicalQuantity extends Comparable toUnit(U targetUnit); + /** + * Convert the physical quantity to a target unit. + * + * @param targetUnit The target unit to convert to provided unit as string. + * @return A new physical quantity converted to the target unit. + * @throws UnitSystemParseException in case of invalid symbol. + */ + PhysicalQuantity toUnit(String targetUnit); + /** * Get the symbol of the unit associated with the physical quantity. * diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Angle.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Angle.java index b943e1d..65265e7 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Angle.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Angle.java @@ -19,7 +19,6 @@ public Angle(double value, AngleUnit unitType) { this.baseValue = unitType.toValueInBaseUnit(value); } - // Static factory methods public static Angle of(double value, AngleUnit unit) { return new Angle(value, unit); @@ -66,6 +65,12 @@ public Angle toUnit(AngleUnit targetUnit) { return Angle.of(valueInTargetUnit, targetUnit); } + @Override + public Angle toUnit(String targetUnit) { + AngleUnit resolvedUnit = AngleUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Angle withValue(double value) { return Angle.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Area.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Area.java index 4b236fa..b0c6939 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Area.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Area.java @@ -102,6 +102,12 @@ public Area toUnit(AreaUnit targetUnit) { return Area.of(valueInTargetUnit, targetUnit); } + @Override + public Area toUnit(String targetUnit) { + AreaUnit resolvedUnit = AreaUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Area withValue(double value) { return Area.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Distance.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Distance.java index 5d554c4..7dfc710 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Distance.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Distance.java @@ -90,6 +90,12 @@ public Distance toUnit(DistanceUnit targetUnit) { return Distance.of(valueInTargetUnit, targetUnit); } + @Override + public Distance toUnit(String targetUnit) { + DistanceUnit resolvedUnit = DistanceUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Distance withValue(double value) { return Distance.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Mass.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Mass.java index 68223c2..c60a4d1 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Mass.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Mass.java @@ -13,7 +13,7 @@ public class Mass implements CalculableQuantity { public Mass(double value, MassUnit unitType) { this.value = value; - if(unitType == null){ + if (unitType == null) { unitType = MassUnits.getDefaultUnit(); } this.unitType = unitType; @@ -29,7 +29,7 @@ public static Mass of(double value, String unitSymbol) { MassUnit resolvedUnit = MassUnits.fromSymbol(unitSymbol); return new Mass(value, resolvedUnit); } - + public static Mass ofKilograms(double value) { return new Mass(value, MassUnits.KILOGRAM); } @@ -82,6 +82,12 @@ public Mass toUnit(MassUnit targetUnit) { return Mass.of(valueInTargetUnit, targetUnit); } + @Override + public Mass toUnit(String targetUnit) { + MassUnit resolvedUnit = MassUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Mass withValue(double value) { return Mass.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Velocity.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Velocity.java index d84f8a3..c315684 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Velocity.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Velocity.java @@ -89,6 +89,12 @@ public Velocity toUnit(VelocityUnit targetUnit) { return Velocity.of(valueInTargetUnit, targetUnit); } + @Override + public Velocity toUnit(String targetUnit) { + VelocityUnit resolvedUnit = VelocityUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Velocity withValue(double value) { return Velocity.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Volume.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Volume.java index 4bea34d..0af499c 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Volume.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Volume.java @@ -89,6 +89,12 @@ public Volume toUnit(VolumeUnit targetUnit) { return Volume.of(valueInTargetUnit, targetUnit); } + @Override + public Volume toUnit(String targetUnit) { + VolumeUnit resolvedUnit = VolumeUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Volume withValue(double value) { return Volume.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/BypassFactor.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/BypassFactor.java index ecc950d..8be0d4e 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/BypassFactor.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/BypassFactor.java @@ -49,6 +49,11 @@ public BypassFactor toUnit(BypassFactorUnit targetUnit) { return this; } + @Override + public BypassFactor toUnit(String targetUnit) { + return this; + } + @Override public BypassFactor withValue(double value) { return BypassFactor.of(value); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/GrashofNumber.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/GrashofNumber.java index 14e05fa..6f0ba62 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/GrashofNumber.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/GrashofNumber.java @@ -45,6 +45,11 @@ public GrashofNumber toUnit(GrashofNumberUnit targetUnit) { return this; } + @Override + public GrashofNumber toUnit(String targetUnit) { + return this; + } + @Override public GrashofNumber withValue(double value) { return GrashofNumber.of(value); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/PrandtlNumber.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/PrandtlNumber.java index 2800f07..d594670 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/PrandtlNumber.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/PrandtlNumber.java @@ -45,6 +45,11 @@ public PrandtlNumber toUnit(PrandtlNumberUnit targetUnit) { return this; } + @Override + public PrandtlNumber toUnit(String targetUnit) { + return this; + } + @Override public PrandtlNumber withValue(double value) { return PrandtlNumber.of(value); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/ReynoldsNumber.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/ReynoldsNumber.java index bc39698..2987334 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/ReynoldsNumber.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/dimensionless/ReynoldsNumber.java @@ -49,6 +49,11 @@ public ReynoldsNumber toUnit(ReynoldsNumberUnit targetUnit) { return this; } + @Override + public ReynoldsNumber toUnit(String targetUnit) { + return this; + } + @Override public ReynoldsNumber withValue(double value) { return ReynoldsNumber.of(value); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/flow/MassFlow.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/flow/MassFlow.java index 8bc1516..e1a5aa1 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/flow/MassFlow.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/flow/MassFlow.java @@ -74,6 +74,12 @@ public MassFlow toUnit(MassFlowUnit targetUnit) { return MassFlow.of(valueInTargetUnit, targetUnit); } + @Override + public MassFlow toUnit(String targetUnit) { + MassFlowUnit resolvedUnit = MassFlowUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public MassFlow withValue(double value) { return MassFlow.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/flow/VolumetricFlow.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/flow/VolumetricFlow.java index 19a6b87..f0ca130 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/flow/VolumetricFlow.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/flow/VolumetricFlow.java @@ -98,6 +98,12 @@ public VolumetricFlow toUnit(VolumetricFlowUnit targetUnit) { return VolumetricFlow.of(valueInTargetUnit, targetUnit); } + @Override + public VolumetricFlow toUnit(String targetUnit) { + VolumetricFlowUnit resolvedUnit = VolumetricFlowUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public VolumetricFlow withValue(double value) { return VolumetricFlow.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/GeoDistance.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/GeoDistance.java index 23a95e6..45c0e33 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/GeoDistance.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/GeoDistance.java @@ -268,6 +268,12 @@ public GeoDistance toUnit(DistanceUnit targetUnit) { return GeoDistance.of(startCoordinate, targetCoordinate, targetUnit); } + @Override + public GeoDistance toUnit(String targetUnit) { + DistanceUnit resolvedUnit = DistanceUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/Latitude.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/Latitude.java index c47a935..d671530 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/Latitude.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/Latitude.java @@ -86,6 +86,12 @@ public Latitude toUnit(AngleUnit targetUnit) { return Latitude.of(valueInTargetUnit, targetUnit); } + @Override + public Latitude toUnit(String targetUnit) { + AngleUnit resolvedUnit = AngleUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Latitude withValue(double value) { return Latitude.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/Longitude.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/Longitude.java index d537c1b..9e3b427 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/Longitude.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/geographic/Longitude.java @@ -85,6 +85,12 @@ public Longitude toUnit(AngleUnit targetUnit) { return Longitude.of(valueInTargetUnit, targetUnit); } + @Override + public Longitude toUnit(String targetUnit) { + AngleUnit resolvedUnit = AngleUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Longitude withValue(double value) { return Longitude.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/humidity/HumidityRatio.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/humidity/HumidityRatio.java index 460423d..26155fe 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/humidity/HumidityRatio.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/humidity/HumidityRatio.java @@ -66,6 +66,12 @@ public HumidityRatio toUnit(HumidityRatioUnit targetUnit) { return HumidityRatio.of(valueInTargetUnit, targetUnit); } + @Override + public HumidityRatio toUnit(String targetUnit) { + HumidityRatioUnit resolvedUnit = HumidityRatioUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public HumidityRatio withValue(double value) { return HumidityRatio.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/humidity/RelativeHumidity.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/humidity/RelativeHumidity.java index 81e6960..ec64cd5 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/humidity/RelativeHumidity.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/humidity/RelativeHumidity.java @@ -67,6 +67,12 @@ public RelativeHumidity toUnit(RelativeHumidityUnit targetUnit) { return RelativeHumidity.of(valueInTargetUnit, targetUnit); } + @Override + public RelativeHumidity toUnit(String targetUnit) { + RelativeHumidityUnit resolvedUnit = RelativeHumidityUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public RelativeHumidity withValue(double value) { return RelativeHumidity.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Force.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Force.java index 4bead04..cd126a9 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Force.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Force.java @@ -81,6 +81,12 @@ public Force toUnit(ForceUnit targetUnit) { return Force.of(valueInTargetUnit, targetUnit); } + @Override + public Force toUnit(String targetUnit) { + ForceUnit resolvedUnit = ForceUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Force withValue(double value) { return Force.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Momentum.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Momentum.java index 15f5141..d568326 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Momentum.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Momentum.java @@ -69,6 +69,12 @@ public Momentum toUnit(MomentumUnit targetUnit) { return Momentum.of(valueInTargetUnit, targetUnit); } + @Override + public Momentum toUnit(String targetUnit) { + MomentumUnit resolvedUnit = MomentumUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Momentum withValue(double value) { return Momentum.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Torque.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Torque.java index dd37824..c73892a 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Torque.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/mechanical/Torque.java @@ -78,6 +78,12 @@ public Torque toUnit(TorqueUnit targetUnit) { return Torque.of(valueInTargetUnit, targetUnit); } + @Override + public Torque toUnit(String targetUnit) { + TorqueUnit resolvedUnit = TorqueUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Torque withValue(double value) { return Torque.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Density.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Density.java index 61f9f50..4d3c2ca 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Density.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Density.java @@ -66,6 +66,12 @@ public Density toUnit(DensityUnit targetUnit) { return Density.of(valueInTargetUnit, targetUnit); } + @Override + public Density toUnit(String targetUnit) { + DensityUnit resolvedUnit = DensityUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Density withValue(double value) { return Density.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/DynamicViscosity.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/DynamicViscosity.java index d7fb109..2b753f5 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/DynamicViscosity.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/DynamicViscosity.java @@ -69,6 +69,12 @@ public DynamicViscosity toUnit(DynamicViscosityUnit targetUnit) { return DynamicViscosity.of(valueInTargetUnit, targetUnit); } + @Override + public DynamicViscosity toUnit(String targetUnit) { + DynamicViscosityUnit resolvedUnit = DynamicViscosityUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public DynamicViscosity withValue(double value) { return DynamicViscosity.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Energy.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Energy.java index 0e79067..fe0e60f 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Energy.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Energy.java @@ -93,6 +93,12 @@ public Energy toUnit(EnergyUnit targetUnit) { return Energy.of(valueInTargetUnit, targetUnit); } + @Override + public Energy toUnit(String targetUnit) { + EnergyUnit resolvedUnit = EnergyUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Energy withValue(double value) { return Energy.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/KinematicViscosity.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/KinematicViscosity.java index bd2cf7f..787e613 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/KinematicViscosity.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/KinematicViscosity.java @@ -65,6 +65,12 @@ public KinematicViscosity toUnit(KinematicViscosityUnit targetUnit) { return KinematicViscosity.of(valueInTargetUnit, targetUnit); } + @Override + public KinematicViscosity toUnit(String targetUnit) { + KinematicViscosityUnit resolvedUnit = KinematicViscosityUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public KinematicViscosity withValue(double value) { return KinematicViscosity.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Power.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Power.java index 1dcfccf..4314c38 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Power.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Power.java @@ -76,6 +76,12 @@ public Power toUnit(PowerUnit targetUnit) { return Power.of(valueInTargetUnit, targetUnit); } + @Override + public Power toUnit(String targetUnit) { + PowerUnit resolvedUnit = PowerUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Power withValue(double value) { return Power.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Pressure.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Pressure.java index 91543c2..a12c7f7 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Pressure.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Pressure.java @@ -87,6 +87,12 @@ public Pressure toUnit(PressureUnit targetUnit) { return Pressure.of(valueInTargetUnit, targetUnit); } + @Override + public Pressure toUnit(String targetUnit) { + PressureUnit resolvedUnit = PressureUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Pressure withValue(double value) { return Pressure.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/SpecificEnthalpy.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/SpecificEnthalpy.java index 0a21f21..298237b 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/SpecificEnthalpy.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/SpecificEnthalpy.java @@ -68,6 +68,12 @@ public SpecificEnthalpy toUnit(SpecificEnthalpyUnit targetUnit) { return SpecificEnthalpy.of(valueInTargetUnit, targetUnit); } + @Override + public SpecificEnthalpy toUnit(String targetUnit) { + SpecificEnthalpyUnit resolvedUnit = SpecificEnthalpyUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public SpecificEnthalpy withValue(double value) { return SpecificEnthalpy.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/SpecificHeat.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/SpecificHeat.java index dd07f7b..2a345ab 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/SpecificHeat.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/SpecificHeat.java @@ -68,6 +68,12 @@ public SpecificHeat toUnit(SpecificHeatUnit targetUnit) { return SpecificHeat.of(valueInTargetUnit, targetUnit); } + @Override + public SpecificHeat toUnit(String targetUnit) { + SpecificHeatUnit resolvedUnit = SpecificHeatUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public SpecificHeat withValue(double value) { return SpecificHeat.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Temperature.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Temperature.java index e9871dd..93066b4 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Temperature.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/Temperature.java @@ -70,6 +70,12 @@ public Temperature toUnit(TemperatureUnit targetUnit) { return Temperature.of(valueInTargetUnit, targetUnit); } + @Override + public Temperature toUnit(String targetUnit) { + TemperatureUnit resolvedUnit = TemperatureUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public Temperature withValue(double value) { return Temperature.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/ThermalConductivity.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/ThermalConductivity.java index c27186c..cfcb44f 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/ThermalConductivity.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/ThermalConductivity.java @@ -68,6 +68,12 @@ public ThermalConductivity toUnit(ThermalConductivityUnit targetUnit) { return ThermalConductivity.of(valueInTargetUnit, targetUnit); } + @Override + public ThermalConductivity toUnit(String targetUnit) { + ThermalConductivityUnit resolvedUnit = ThermalConductivityUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public ThermalConductivity withValue(double value) { return ThermalConductivity.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/ThermalDiffusivity.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/ThermalDiffusivity.java index 5785033..a8db603 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/ThermalDiffusivity.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/thermodynamic/ThermalDiffusivity.java @@ -65,6 +65,12 @@ public ThermalDiffusivity toUnit(ThermalDiffusivityUnit targetUnit) { return ThermalDiffusivity.of(valueInTargetUnit, targetUnit); } + @Override + public ThermalDiffusivity toUnit(String targetUnit) { + ThermalDiffusivityUnit resolvedUnit = ThermalDiffusivityUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public ThermalDiffusivity withValue(double value) { return ThermalDiffusivity.of(value, unitType); diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityInfo.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityInfo.java new file mode 100644 index 0000000..c09abc4 --- /dev/null +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityInfo.java @@ -0,0 +1,8 @@ +package com.synerset.unitility.unitsystem.util; + +import java.util.List; + +public record PhysicalQuantityInfo( + Class quantityClass, + List supportedUnits +) {} \ No newline at end of file diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalUnitInfo.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalUnitInfo.java new file mode 100644 index 0000000..efc78ab --- /dev/null +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalUnitInfo.java @@ -0,0 +1,7 @@ +package com.synerset.unitility.unitsystem.util; + +public record PhysicalUnitInfo( + String unitName, + String unitSymbol +) { +} diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/StringTransformer.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/StringTransformer.java index f8eced2..1e11845 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/StringTransformer.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/StringTransformer.java @@ -65,6 +65,7 @@ public StringTransformer unifyMultiAndDiv() { inputString.replace(".", "") .replace("ยท", "") .replace("x", "") + .replace("*", "") .replace("/", "p")); } diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/SupportedQuantitiesRegistry.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/SupportedQuantitiesRegistry.java new file mode 100644 index 0000000..46126e4 --- /dev/null +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/SupportedQuantitiesRegistry.java @@ -0,0 +1,151 @@ +package com.synerset.unitility.unitsystem.util; + +import com.synerset.unitility.unitsystem.PhysicalQuantity; +import com.synerset.unitility.unitsystem.Unit; +import com.synerset.unitility.unitsystem.common.*; +import com.synerset.unitility.unitsystem.dimensionless.BypassFactor; +import com.synerset.unitility.unitsystem.dimensionless.GrashofNumber; +import com.synerset.unitility.unitsystem.dimensionless.PrandtlNumber; +import com.synerset.unitility.unitsystem.dimensionless.ReynoldsNumber; +import com.synerset.unitility.unitsystem.flow.MassFlow; +import com.synerset.unitility.unitsystem.flow.MassFlowUnits; +import com.synerset.unitility.unitsystem.flow.VolumetricFlow; +import com.synerset.unitility.unitsystem.flow.VolumetricFlowUnits; +import com.synerset.unitility.unitsystem.geographic.GeoDistance; +import com.synerset.unitility.unitsystem.geographic.Latitude; +import com.synerset.unitility.unitsystem.geographic.Longitude; +import com.synerset.unitility.unitsystem.humidity.HumidityRatio; +import com.synerset.unitility.unitsystem.humidity.HumidityRatioUnits; +import com.synerset.unitility.unitsystem.humidity.RelativeHumidity; +import com.synerset.unitility.unitsystem.humidity.RelativeHumidityUnits; +import com.synerset.unitility.unitsystem.mechanical.*; +import com.synerset.unitility.unitsystem.thermodynamic.*; + +import java.util.*; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * The {@link SupportedQuantitiesRegistry} class provides a registry for physical quantities and their supported units. + * It allows retrieval of unit information for various physical quantities that are registered within the system. + */ +public class SupportedQuantitiesRegistry { + + private static final SupportedQuantitiesRegistry UNIT_REGISTRY = new SupportedQuantitiesRegistry(); + + private final Map, Supplier>> immutableRegistry; + + private SupportedQuantitiesRegistry() { + // Initializing immutable registry + this.immutableRegistry = Map.ofEntries( + // Common + Map.entry(Angle.class, () -> Arrays.asList(AngleUnits.values())), + Map.entry(Area.class, () -> Arrays.asList(AreaUnits.values())), + Map.entry(Distance.class, () -> Arrays.asList(DistanceUnits.values())), + Map.entry(Mass.class, () -> Arrays.asList(MassUnits.values())), + Map.entry(Velocity.class, () -> Arrays.asList(VelocityUnits.values())), + Map.entry(Volume.class, () -> Arrays.asList(VolumeUnits.values())), + // Dimensionless + Map.entry(BypassFactor.class, Collections::emptyList), + Map.entry(GrashofNumber.class, Collections::emptyList), + Map.entry(PrandtlNumber.class, Collections::emptyList), + Map.entry(ReynoldsNumber.class, Collections::emptyList), + // Flows + Map.entry(MassFlow.class, () -> Arrays.asList(MassFlowUnits.values())), + Map.entry(VolumetricFlow.class, () -> Arrays.asList(VolumetricFlowUnits.values())), + // Humidity + Map.entry(HumidityRatio.class, () -> Arrays.asList(HumidityRatioUnits.values())), + Map.entry(RelativeHumidity.class, () -> Arrays.asList(RelativeHumidityUnits.values())), + // Mechanical + Map.entry(Force.class, () -> Arrays.asList(ForceUnits.values())), + Map.entry(Momentum.class, () -> Arrays.asList(MomentumUnits.values())), + Map.entry(Torque.class, () -> Arrays.asList(TorqueUnits.values())), + // Thermodynamic + Map.entry(Density.class, () -> Arrays.asList(DensityUnits.values())), + Map.entry(DynamicViscosity.class, () -> Arrays.asList(DynamicViscosityUnits.values())), + Map.entry(Energy.class, () -> Arrays.asList(EnergyUnits.values())), + Map.entry(KinematicViscosity.class, () -> Arrays.asList(KinematicViscosityUnits.values())), + Map.entry(Power.class, () -> Arrays.asList(PowerUnits.values())), + Map.entry(Pressure.class, () -> Arrays.asList(PressureUnits.values())), + Map.entry(SpecificEnthalpy.class, () -> Arrays.asList(SpecificEnthalpyUnits.values())), + Map.entry(SpecificHeat.class, () -> Arrays.asList(SpecificHeatUnits.values())), + Map.entry(Temperature.class, () -> Arrays.asList(TemperatureUnits.values())), + Map.entry(ThermalConductivity.class, () -> Arrays.asList(ThermalConductivityUnits.values())), + Map.entry(ThermalDiffusivity.class, () -> Arrays.asList(ThermalDiffusivityUnits.values())), + // Geographic + Map.entry(Latitude.class, () -> Arrays.asList(AngleUnits.values())), + Map.entry(Longitude.class, () -> Arrays.asList(AngleUnits.values())), + Map.entry(GeoDistance.class, () -> Arrays.asList(DistanceUnits.values())) + ); + } + + /** + * Retrieves a set of {@link PhysicalQuantityInfo}, representing supported registered physical quantities and associated + * units including their symbols. + * + * @return A set {@link PhysicalQuantityInfo} representing supported physical quantities. + */ + public Set findAllSupportedQuantities() { + return immutableRegistry.entrySet().stream() + .map(entry -> { + Class quantityClass = entry.getKey(); + List supportedUnits = entry.getValue().get().stream() + .map(unit -> { + String name = getEnumName(unit); + String symbol = unit.getSymbol(); + return new PhysicalUnitInfo(name, symbol); + }) + .toList(); + return new PhysicalQuantityInfo(quantityClass, supportedUnits); + }) + .collect(Collectors.toSet()); + } + + /** + * Retrieves {@link PhysicalQuantityInfo} for a specific class. + * + * @param clazz The class of the physical quantity to retrieve. + * @return The {@link PhysicalQuantityInfo} for the given class, or an empty Optional if not found. + */ + public Optional findQuantityInfoByClass(Class clazz) { + return Optional.ofNullable(immutableRegistry.get(clazz)) + .map(supplier -> { + List supportedUnits = supplier.get().stream() + .map(unit -> { + String name = getEnumName(unit); + String symbol = unit.getSymbol(); + return new PhysicalUnitInfo(name, symbol); + }) + .toList(); + return new PhysicalQuantityInfo(clazz, supportedUnits); + }); + } + + /** + * Retrieves a set of all registered physical quantity classes. + * + * @param The type of unit associated with the physical quantity. + * @param The type of physical quantity. + * @return A set containing all registered physical quantity classes. + */ + @SuppressWarnings("unchecked") + public > Set> findAllRegisteredClasses() { + Set> quantityClasses = new HashSet<>(); + immutableRegistry.keySet().forEach(quantityClass -> quantityClasses.add((Class) quantityClass)); + return quantityClasses; + } + + private String getEnumName(Unit unit) { + // Check if the unit is an instance of Enum + if (unit instanceof Enum) { + return ((Enum) unit).name(); + } + // Handle case where unit is not an Enum + return "Unknown"; + } + + public static SupportedQuantitiesRegistry getInstance() { + return UNIT_REGISTRY; + } + +} \ No newline at end of file diff --git a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/PhysicalQuantityTest.java b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/PhysicalQuantityTest.java index cac09e8..7472d21 100644 --- a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/PhysicalQuantityTest.java +++ b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/PhysicalQuantityTest.java @@ -2,7 +2,9 @@ import com.synerset.unitility.unitsystem.common.Distance; import com.synerset.unitility.unitsystem.common.DistanceUnits; +import com.synerset.unitility.unitsystem.common.Volume; import com.synerset.unitility.unitsystem.dimensionless.BypassFactor; +import com.synerset.unitility.unitsystem.exceptions.UnitSystemParseException; import com.synerset.unitility.unitsystem.flow.VolumetricFlow; import com.synerset.unitility.unitsystem.flow.VolumetricFlowUnit; import com.synerset.unitility.unitsystem.thermodynamic.Pressure; @@ -14,6 +16,7 @@ import java.util.Arrays; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; class PhysicalQuantityTest { @@ -104,7 +107,6 @@ void isCloseToZero_shouldEvaluateIfCloseToZero(){ } // Others - @Test @DisplayName("should return property unit symbol") void getUnitSymbol_shouldReturnPropertyUnitSymbol() { @@ -183,4 +185,19 @@ void toUnitFrom_shouldUseUnitFromFromOtherQuantity(){ assertThat(actualVolFlow.getValue()).isEqualTo(7200); } + @Test + @DisplayName("Should convert value to provided target unit as string") + void toUnit_shouldConvertValueToProvidedTargetUnit(){ + // Given + Volume volumeInM3 = Volume.ofCubicMeters(1); + + // When + Volume volumeInCm3 = volumeInM3.toUnit(" c m 3 "); + + // Then + assertThat(volumeInCm3.getValue()).isEqualTo(1000); + assertThatThrownBy(() -> volumeInCm3.toUnit("kg")).isInstanceOf(UnitSystemParseException.class); + + } + } \ No newline at end of file diff --git a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/customunit/CustomAngle.java b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/customunit/CustomAngle.java index f032fe6..7d1f67d 100644 --- a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/customunit/CustomAngle.java +++ b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/customunit/CustomAngle.java @@ -56,6 +56,12 @@ public CustomAngle toUnit(AngleUnit targetUnit) { return CustomAngle.of(valueInTargetUnit, targetUnit); } + @Override + public CustomAngle toUnit(String targetUnit) { + AngleUnit resolvedUnit = CustomAngleUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + @Override public CustomAngle withValue(double value) { return CustomAngle.of(value, unitType); diff --git a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityParsingFactoryTest.java b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityParsingFactoryTest.java index 6a01a2d..60a432c 100644 --- a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityParsingFactoryTest.java +++ b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityParsingFactoryTest.java @@ -34,7 +34,7 @@ class PhysicalQuantityParsingFactoryTest { - PhysicalQuantityParsingFactory PARSING_FACTORY = PhysicalQuantityParsingFactory.getDefaultParsingFactory(); + private static final PhysicalQuantityParsingFactory PARSING_FACTORY = PhysicalQuantityParsingFactory.getDefaultParsingFactory(); @Test @DisplayName("should create default parsing registry with registered parsers") @@ -239,6 +239,11 @@ public PhysicalQuantity toUnit(DistanceUnit targetUnit) { return null; } + @Override + public PhysicalQuantity toUnit(String targetUnit) { + return null; + } + @Override public TestClass withValue(double value) { diff --git a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/util/SupportedQuantitiesRegistryTest.java b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/util/SupportedQuantitiesRegistryTest.java new file mode 100644 index 0000000..d06536e --- /dev/null +++ b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/util/SupportedQuantitiesRegistryTest.java @@ -0,0 +1,61 @@ +package com.synerset.unitility.unitsystem.util; + +import com.synerset.unitility.unitsystem.PhysicalQuantity; +import com.synerset.unitility.unitsystem.Unit; +import com.synerset.unitility.unitsystem.thermodynamic.Temperature; +import com.synerset.unitility.unitsystem.thermodynamic.TemperatureUnits; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class SupportedQuantitiesRegistryTest { + + private static final SupportedQuantitiesRegistry QUANTITY_REGISTRY = SupportedQuantitiesRegistry.getInstance(); + private static final PhysicalQuantityParsingFactory PARSING_FACTORY = PhysicalQuantityParsingFactory.getDefaultParsingFactory(); + + @Test + @DisplayName("Supported quantity registry: should find all supported quantities and associated units") + void findAllSupportedQuantities_shouldFindAllSupportedQuantitiesAndAssociatedUnits() { + // Given + // When + Set allSupportedQuantities = QUANTITY_REGISTRY.findAllSupportedQuantities(); + + // Then + assertThat(allSupportedQuantities).isNotNull().isNotEmpty().hasSize(31); + } + + @Test + @DisplayName("Supported quantity registry: all parsing registry quantity classes should be included in quantity registry") + void findAllSupportedQuantities_shouldAllParsingFactoryClassesBePresentInQuantityRegistry() { + // Given + Set>> registeredSupportedQuantityClasses = QUANTITY_REGISTRY.findAllRegisteredClasses(); + Set>> registeredParsingFactoryClasses = PARSING_FACTORY.findAllRegisteredClasses(); + + // When + // Then + assertThat(registeredSupportedQuantityClasses).containsAll(registeredParsingFactoryClasses); + } + + @Test + @DisplayName("Supported quantity registry: should find registered quantity info based on provided class") + void findQuantityInfoByClass_should_shouldFindRegisteredQuantityInfoWhenClassIsGiven() { + // Given + Class temperatureClass = Temperature.class; + + // When + PhysicalQuantityInfo physicalQuantityInfo = QUANTITY_REGISTRY.findQuantityInfoByClass(temperatureClass).orElse(null); + + // Then + assertThat(physicalQuantityInfo).isNotNull(); + assertThat(physicalQuantityInfo.quantityClass()).isEqualTo(temperatureClass); + assertThat(physicalQuantityInfo.supportedUnits()).isNotNull().hasSize(TemperatureUnits.values().length); + List temperatureSymbols = Arrays.stream(TemperatureUnits.values()).map(TemperatureUnits::getSymbol).toList(); + assertThat(physicalQuantityInfo.supportedUnits()).extracting(PhysicalUnitInfo::unitSymbol).containsAll(temperatureSymbols); + } + +} \ No newline at end of file