From b0338bfeb9184304fac6177cd85a08e4ac4ad365 Mon Sep 17 00:00:00 2001 From: Piotr Jazdzyk Date: Sat, 13 Sep 2025 17:01:21 +0200 Subject: [PATCH 1/3] SNSUNI-139: Change FEET to FOOT for uniformity across other units --- .../com/synerset/unitility/unitsystem/common/Volume.java | 6 +++--- .../synerset/unitility/unitsystem/common/VolumeUnits.java | 2 +- .../synerset/unitility/unitsystem/common/VolumeTest.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) 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 7161fff..1b992ce 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 @@ -70,7 +70,7 @@ public static Volume ofGallonsUK(double value) { } public static Volume ofCubicFeet(double value) { // New method - return new Volume(value, VolumeUnits.CUBIC_FEET); + return new Volume(value, VolumeUnits.CUBIC_FOOT); } @Override @@ -154,7 +154,7 @@ public Volume toGallonUK() { } public Volume toCubicFeet() { // New method - return toUnit(VolumeUnits.CUBIC_FEET); + return toUnit(VolumeUnits.CUBIC_FOOT); } // Get value in target unit @@ -199,7 +199,7 @@ public double getInGallonsUK() { } public double getInCubicFeet() { // New method - return getInUnit(VolumeUnits.CUBIC_FEET); + return getInUnit(VolumeUnits.CUBIC_FOOT); } @Override diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/VolumeUnits.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/VolumeUnits.java index 292c290..b84c179 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/VolumeUnits.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/VolumeUnits.java @@ -10,7 +10,7 @@ public enum VolumeUnits implements VolumeUnit { CUBIC_METER("m³", val -> val, val -> val), CUBIC_CENTIMETER("cm³", val -> val * 0.000001, val -> val * 1000000.0), CUBIC_DECIMETER("dm³", val -> val * 0.001, val -> val * 1000.0), - CUBIC_FEET("ft³", val -> val * 0.0283168466, val -> val / 0.0283168466), + CUBIC_FOOT("ft³", val -> val * 0.0283168466, val -> val / 0.0283168466), LITRE("l", val -> val * 0.001, val -> val * 1000.0), HECTOLITRE("hl", val -> val * 0.1, val -> val * 10.0), MILLILITRE("ml", val -> val * 0.000001, val -> val * 1000000.0), diff --git a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/VolumeTest.java b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/VolumeTest.java index e1c5820..ed7d67b 100644 --- a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/VolumeTest.java +++ b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/VolumeTest.java @@ -158,7 +158,7 @@ void shouldProperlyConvertToCubicMetersFromCubicFeet() { // When Volume actualInCubicMeter = initialVolumeInCubicFeet.toBaseUnit(); - Volume actualInCubicFeet = actualInCubicMeter.toUnit(VolumeUnits.CUBIC_FEET); + Volume actualInCubicFeet = actualInCubicMeter.toUnit(VolumeUnits.CUBIC_FOOT); double actualInCubicFeetVal = actualInCubicMeter.getInCubicFeet(); // Then From 254cce211d1428510769dc57dbe0a5057bce789d Mon Sep 17 00:00:00 2001 From: Piotr Jazdzyk Date: Sat, 13 Sep 2025 17:03:56 +0200 Subject: [PATCH 2/3] SNSUNI-140: Add Thickness and AbsoluteRoughness quantities --- pom.xml | 2 +- .../unitsystem/common/Thickness.java | 193 +++++++++++++++++ .../hydraulic/AbsoluteRoughness.java | 195 ++++++++++++++++++ ...PhysicalQuantityDefaultParsingFactory.java | 4 + .../util/SupportedQuantitiesRegistry.java | 2 + .../unitsystem/common/ThicknessTest.java | 175 ++++++++++++++++ .../hydraulic/AbsoluteRoughnessTest.java | 177 ++++++++++++++++ .../util/SupportedQuantitiesRegistryTest.java | 2 +- .../AbsoluteRoughnessPlainSiConverter.java | 25 +++ .../common/ThicknessPlainSiConverter.java | 25 +++ .../plainsivalue/PlainSiConverterTest.java | 42 ++++ 11 files changed, 840 insertions(+), 2 deletions(-) create mode 100644 unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Thickness.java create mode 100644 unitility-core/src/main/java/com/synerset/unitility/unitsystem/hydraulic/AbsoluteRoughness.java create mode 100644 unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/ThicknessTest.java create mode 100644 unitility-core/src/test/java/com/synerset/unitility/unitsystem/hydraulic/AbsoluteRoughnessTest.java create mode 100644 unitility-persistence/src/main/java/com/synerset/unitility/persistence/converter/plainsivalue/common/AbsoluteRoughnessPlainSiConverter.java create mode 100644 unitility-persistence/src/main/java/com/synerset/unitility/persistence/converter/plainsivalue/common/ThicknessPlainSiConverter.java diff --git a/pom.xml b/pom.xml index 2dbfead..5e5d65b 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ - 2.11.0 + 2.12.0 17 diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Thickness.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Thickness.java new file mode 100644 index 0000000..57c7ebe --- /dev/null +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/Thickness.java @@ -0,0 +1,193 @@ +package com.synerset.unitility.unitsystem.common; + +import com.synerset.unitility.unitsystem.CalculableQuantity; +import com.synerset.unitility.unitsystem.PhysicalQuantity; + +import java.util.Objects; + +public class Thickness implements CalculableQuantity { + + public static final Thickness PHYSICAL_MIN_LIMIT = Thickness.ofMeters(0); + private final double value; + private final double baseValue; + private final DistanceUnit unitType; + + public Thickness(double value, DistanceUnit unitType) { + this.value = value; + if (unitType == null) { + unitType = DistanceUnits.METER; + } + this.unitType = unitType; + this.baseValue = unitType.toValueInBaseUnit(value); + } + + // Static factory methods + public static Thickness of(double value, DistanceUnit unit) { + return new Thickness(value, unit); + } + + public static Thickness of(double value, String unitSymbol) { + DistanceUnit resolvedUnit = DistanceUnits.fromSymbol(unitSymbol); + return new Thickness(value, resolvedUnit); + } + + public static Thickness ofMeters(double value) { + return new Thickness(value, DistanceUnits.METER); + } + + public static Thickness ofCentimeters(double value) { + return new Thickness(value, DistanceUnits.CENTIMETER); + } + + public static Thickness ofMillimeters(double value) { + return new Thickness(value, DistanceUnits.MILLIMETER); + } + + public static Thickness ofKilometers(double value) { + return new Thickness(value, DistanceUnits.KILOMETER); + } + + public static Thickness ofMiles(double value) { + return new Thickness(value, DistanceUnits.MILE); + } + + public static Thickness ofNauticalMiles(double value) { + return new Thickness(value, DistanceUnits.NAUTICAL_MILE); + } + + public static Thickness ofFeet(double value) { + return new Thickness(value, DistanceUnits.FEET); + } + + public static Thickness ofInches(double value) { + return new Thickness(value, DistanceUnits.INCH); + } + + @Override + public double getValue() { + return value; + } + + @Override + public double getBaseValue() { + return baseValue; + } + + @Override + public DistanceUnit getUnit() { + return unitType; + } + + @Override + public Thickness toBaseUnit() { + double valueInBaseUnit = unitType.toValueInBaseUnit(value); + return of(valueInBaseUnit, unitType.getBaseUnit()); + } + + @Override + public Thickness toUnit(DistanceUnit targetUnit) { + double valueInMeters = unitType.toValueInBaseUnit(value); + double valueInTargetUnit = targetUnit.fromValueInBaseUnit(valueInMeters); + return Thickness.of(valueInTargetUnit, targetUnit); + } + + @Override + public Thickness toUnit(String targetUnit) { + DistanceUnit resolvedUnit = DistanceUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + + @Override + public Thickness withValue(double value) { + return Thickness.of(value, unitType); + } + + // Convert to target unit + public Thickness toMeter() { + return toUnit(DistanceUnits.METER); + } + + public Thickness toCentimeter() { + return toUnit(DistanceUnits.CENTIMETER); + } + + public Thickness toMillimeter() { + return toUnit(DistanceUnits.MILLIMETER); + } + + public Thickness toKilometer() { + return toUnit(DistanceUnits.KILOMETER); + } + + public Thickness toMile() { + return toUnit(DistanceUnits.MILE); + } + + public Thickness toNauticalMile() { + return toUnit(DistanceUnits.NAUTICAL_MILE); + } + + public Thickness toFeet() { + return toUnit(DistanceUnits.FEET); + } + + public Thickness toInch() { + return toUnit(DistanceUnits.INCH); + } + + // Get value in target unit + public double getInMeters() { + return getInUnit(DistanceUnits.METER); + } + + public double getInCentimeters() { + return getInUnit(DistanceUnits.CENTIMETER); + } + + public double getInMillimeters() { + return getInUnit(DistanceUnits.MILLIMETER); + } + + public double getInKilometers() { + return getInUnit(DistanceUnits.KILOMETER); + } + + public double getInMiles() { + return getInUnit(DistanceUnits.MILE); + } + + public double getInNauticalMiles() { + return getInUnit(DistanceUnits.NAUTICAL_MILE); + } + + public double getInFeet() { + return getInUnit(DistanceUnits.FEET); + } + + public double getInInches() { + return getInUnit(DistanceUnits.INCH); + } + + public static Thickness of(PhysicalQuantity distanceType) { + return Thickness.of(distanceType.getValue(), distanceType.getUnit()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Thickness inputQuantity = (Thickness) o; + return Double.compare(inputQuantity.toBaseUnit().getValue(), baseValue) == 0 && Objects.equals(unitType.getBaseUnit(), inputQuantity.getUnit().getBaseUnit()); + } + + @Override + public int hashCode() { + return Objects.hash(baseValue, unitType.getBaseUnit()); + } + + @Override + public String toString() { + return "Thickness{" + value + " " + unitType.getSymbol() + '}'; + } + +} \ No newline at end of file diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/hydraulic/AbsoluteRoughness.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/hydraulic/AbsoluteRoughness.java new file mode 100644 index 0000000..da567b2 --- /dev/null +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/hydraulic/AbsoluteRoughness.java @@ -0,0 +1,195 @@ +package com.synerset.unitility.unitsystem.hydraulic; + +import com.synerset.unitility.unitsystem.CalculableQuantity; +import com.synerset.unitility.unitsystem.PhysicalQuantity; +import com.synerset.unitility.unitsystem.common.DistanceUnit; +import com.synerset.unitility.unitsystem.common.DistanceUnits; + +import java.util.Objects; + +public class AbsoluteRoughness implements CalculableQuantity { + + public static final AbsoluteRoughness PHYSICAL_MIN_LIMIT = AbsoluteRoughness.ofMeters(0); + private final double value; + private final double baseValue; + private final DistanceUnit unitType; + + public AbsoluteRoughness(double value, DistanceUnit unitType) { + this.value = value; + if (unitType == null) { + unitType = DistanceUnits.METER; + } + this.unitType = unitType; + this.baseValue = unitType.toValueInBaseUnit(value); + } + + // Static factory methods + public static AbsoluteRoughness of(double value, DistanceUnit unit) { + return new AbsoluteRoughness(value, unit); + } + + public static AbsoluteRoughness of(double value, String unitSymbol) { + DistanceUnit resolvedUnit = DistanceUnits.fromSymbol(unitSymbol); + return new AbsoluteRoughness(value, resolvedUnit); + } + + public static AbsoluteRoughness ofMeters(double value) { + return new AbsoluteRoughness(value, DistanceUnits.METER); + } + + public static AbsoluteRoughness ofCentimeters(double value) { + return new AbsoluteRoughness(value, DistanceUnits.CENTIMETER); + } + + public static AbsoluteRoughness ofMillimeters(double value) { + return new AbsoluteRoughness(value, DistanceUnits.MILLIMETER); + } + + public static AbsoluteRoughness ofKilometers(double value) { + return new AbsoluteRoughness(value, DistanceUnits.KILOMETER); + } + + public static AbsoluteRoughness ofMiles(double value) { + return new AbsoluteRoughness(value, DistanceUnits.MILE); + } + + public static AbsoluteRoughness ofNauticalMiles(double value) { + return new AbsoluteRoughness(value, DistanceUnits.NAUTICAL_MILE); + } + + public static AbsoluteRoughness ofFeet(double value) { + return new AbsoluteRoughness(value, DistanceUnits.FEET); + } + + public static AbsoluteRoughness ofInches(double value) { + return new AbsoluteRoughness(value, DistanceUnits.INCH); + } + + @Override + public double getValue() { + return value; + } + + @Override + public double getBaseValue() { + return baseValue; + } + + @Override + public DistanceUnit getUnit() { + return unitType; + } + + @Override + public AbsoluteRoughness toBaseUnit() { + double valueInBaseUnit = unitType.toValueInBaseUnit(value); + return of(valueInBaseUnit, unitType.getBaseUnit()); + } + + @Override + public AbsoluteRoughness toUnit(DistanceUnit targetUnit) { + double valueInMeters = unitType.toValueInBaseUnit(value); + double valueInTargetUnit = targetUnit.fromValueInBaseUnit(valueInMeters); + return AbsoluteRoughness.of(valueInTargetUnit, targetUnit); + } + + @Override + public AbsoluteRoughness toUnit(String targetUnit) { + DistanceUnit resolvedUnit = DistanceUnits.fromSymbol(targetUnit); + return toUnit(resolvedUnit); + } + + @Override + public AbsoluteRoughness withValue(double value) { + return AbsoluteRoughness.of(value, unitType); + } + + // Convert to target unit + public AbsoluteRoughness toMeter() { + return toUnit(DistanceUnits.METER); + } + + public AbsoluteRoughness toCentimeter() { + return toUnit(DistanceUnits.CENTIMETER); + } + + public AbsoluteRoughness toMillimeter() { + return toUnit(DistanceUnits.MILLIMETER); + } + + public AbsoluteRoughness toKilometer() { + return toUnit(DistanceUnits.KILOMETER); + } + + public AbsoluteRoughness toMile() { + return toUnit(DistanceUnits.MILE); + } + + public AbsoluteRoughness toNauticalMile() { + return toUnit(DistanceUnits.NAUTICAL_MILE); + } + + public AbsoluteRoughness toFeet() { + return toUnit(DistanceUnits.FEET); + } + + public AbsoluteRoughness toInch() { + return toUnit(DistanceUnits.INCH); + } + + // Get value in target unit + public double getInMeters() { + return getInUnit(DistanceUnits.METER); + } + + public double getInCentimeters() { + return getInUnit(DistanceUnits.CENTIMETER); + } + + public double getInMillimeters() { + return getInUnit(DistanceUnits.MILLIMETER); + } + + public double getInKilometers() { + return getInUnit(DistanceUnits.KILOMETER); + } + + public double getInMiles() { + return getInUnit(DistanceUnits.MILE); + } + + public double getInNauticalMiles() { + return getInUnit(DistanceUnits.NAUTICAL_MILE); + } + + public double getInFeet() { + return getInUnit(DistanceUnits.FEET); + } + + public double getInInches() { + return getInUnit(DistanceUnits.INCH); + } + + public static AbsoluteRoughness of(PhysicalQuantity distanceType) { + return AbsoluteRoughness.of(distanceType.getValue(), distanceType.getUnit()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AbsoluteRoughness inputQuantity = (AbsoluteRoughness) o; + return Double.compare(inputQuantity.toBaseUnit().getValue(), baseValue) == 0 && Objects.equals(unitType.getBaseUnit(), inputQuantity.getUnit().getBaseUnit()); + } + + @Override + public int hashCode() { + return Objects.hash(baseValue, unitType.getBaseUnit()); + } + + @Override + public String toString() { + return "AbsoluteRoughness{" + value + " " + unitType.getSymbol() + '}'; + } + +} \ No newline at end of file diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityDefaultParsingFactory.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityDefaultParsingFactory.java index 6e7984c..f4edaf6 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityDefaultParsingFactory.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/util/PhysicalQuantityDefaultParsingFactory.java @@ -42,6 +42,7 @@ private PhysicalQuantityDefaultParsingFactory() { Map.entry(Height.class, Height::of), Map.entry(Diameter.class, Diameter::of), Map.entry(Perimeter.class, Perimeter::of), + Map.entry(Thickness.class, Thickness::of), Map.entry(Mass.class, Mass::of), Map.entry(LinearMassDensity.class, LinearMassDensity::of), Map.entry(Velocity.class, Velocity::of), @@ -67,6 +68,7 @@ private PhysicalQuantityDefaultParsingFactory() { Map.entry(LocalLossFactor.class, (value, symbol) -> LocalLossFactor.of(value)), Map.entry(RotationSpeedToFlowRateRatio.class, RotationSpeedToFlowRateRatio::of), Map.entry(SDR.class, SDR::of), + Map.entry(AbsoluteRoughness.class, AbsoluteRoughness::of), // Mechanical Map.entry(Force.class, Force::of), Map.entry(Momentum.class, Momentum::of), @@ -100,6 +102,7 @@ private PhysicalQuantityDefaultParsingFactory() { Map.entry(Height.class, DistanceUnits.METER), Map.entry(Diameter.class, DistanceUnits.METER), Map.entry(Perimeter.class, DistanceUnits.METER), + Map.entry(Thickness.class, DistanceUnits.METER), Map.entry(Mass.class, MassUnits.KILOGRAM), Map.entry(LinearMassDensity.class, LinearMassDensityUnits.KILOGRAM_PER_METER), Map.entry(Velocity.class, VelocityUnits.METER_PER_SECOND), @@ -125,6 +128,7 @@ private PhysicalQuantityDefaultParsingFactory() { Map.entry(LocalLossFactor.class, LocalLossFactorUnits.DIMENSIONLESS), Map.entry(RotationSpeedToFlowRateRatio.class, RotationSpeedToFlowRateRatioUnits.RADIAN_PER_SECOND_PER_CUBIC_METER_PER_SECOND), Map.entry(SDR.class, RatioUnits.DECIMAL), + Map.entry(AbsoluteRoughness.class, DistanceUnits.METER), // Mechanical (3) Map.entry(Force.class, ForceUnits.NEWTON), Map.entry(Momentum.class, MomentumUnits.KILOGRAM_METER_PER_SECOND), 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 index a7577bb..db90bca 100644 --- 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 @@ -46,6 +46,7 @@ private SupportedQuantitiesRegistry() { Map.entry(Height.class, () -> Arrays.asList(DistanceUnits.values())), Map.entry(Diameter.class, () -> Arrays.asList(DistanceUnits.values())), Map.entry(Perimeter.class, () -> Arrays.asList(DistanceUnits.values())), + Map.entry(Thickness.class, () -> Arrays.asList(DistanceUnits.values())), Map.entry(Mass.class, () -> Arrays.asList(MassUnits.values())), Map.entry(LinearMassDensity.class, () -> Arrays.asList(LinearMassDensityUnits.values())), Map.entry(Velocity.class, () -> Arrays.asList(VelocityUnits.values())), @@ -71,6 +72,7 @@ private SupportedQuantitiesRegistry() { Map.entry(LocalLossFactor.class, Collections::emptyList), Map.entry(RotationSpeedToFlowRateRatio.class, () -> Arrays.asList(RotationSpeedToFlowRateRatioUnits.values())), Map.entry(SDR.class, () -> Arrays.asList(RatioUnits.values())), + Map.entry(AbsoluteRoughness.class, () -> Arrays.asList(DistanceUnits.values())), // Mechanical Map.entry(Force.class, () -> Arrays.asList(ForceUnits.values())), Map.entry(Momentum.class, () -> Arrays.asList(MomentumUnits.values())), diff --git a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/ThicknessTest.java b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/ThicknessTest.java new file mode 100644 index 0000000..f2f06ef --- /dev/null +++ b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/ThicknessTest.java @@ -0,0 +1,175 @@ +package com.synerset.unitility.unitsystem.common; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ThicknessTest { + + @Test + @DisplayName("Thickness: should convert to m from mm and vice versa") + void shouldProperlyConvertToMetersFromMillimeters() { + // Given + Thickness initialThicknessInMillimeters = Thickness.ofMillimeters(1000.0); + + // When + Thickness actualInMeters = initialThicknessInMillimeters.toUnit(DistanceUnits.METER); + double actualInMetersVal = actualInMeters.getInMeters(); + Thickness actualInMillimeters = actualInMeters.toUnit(DistanceUnits.MILLIMETER); + double actualInMillimetersVal = actualInMeters.getInMillimeters(); + + // Then + Thickness expectedInMeters = Thickness.ofMeters(1.0); + assertThat(actualInMeters.getValue()).isEqualTo(actualInMetersVal); + assertThat(actualInMillimeters.getValue()).isEqualTo(actualInMillimetersVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInMillimeters).isEqualTo(initialThicknessInMillimeters); + } + + @Test + @DisplayName("Thickness: should convert to m from cm and vice versa") + void shouldProperlyConvertToMetersFromCentimeters() { + // Given + Thickness initialThicknessInCentimeters = Thickness.ofCentimeters(100.0); + + // When + Thickness actualInMeters = initialThicknessInCentimeters.toBaseUnit(); + Thickness actualInCentimeters = actualInMeters.toUnit(DistanceUnits.CENTIMETER); + double actualInCentimetersVal = actualInMeters.getInCentimeters(); + + // Then + Thickness expectedInMeters = Thickness.ofMeters(1.0); + assertThat(actualInCentimeters.getValue()).isEqualTo(actualInCentimetersVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInCentimeters).isEqualTo(initialThicknessInCentimeters); + } + + @Test + @DisplayName("Thickness: should convert to m from km and vice versa") + void shouldProperlyConvertToMetersFromKilometers() { + // Given + Thickness initialThicknessInKilometers = Thickness.ofKilometers(1.0); + + // When + Thickness actualInMeters = initialThicknessInKilometers.toBaseUnit(); + Thickness actualInKilometers = actualInMeters.toUnit(DistanceUnits.KILOMETER); + double actualInKilometersVal = actualInMeters.getInKilometers(); + + // Then + Thickness expectedInMeters = Thickness.ofMeters(1000.0); + assertThat(actualInKilometers.getValue()).isEqualTo(actualInKilometersVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInKilometers).isEqualTo(initialThicknessInKilometers); + } + + @Test + @DisplayName("Thickness: should convert to m from mi and vice versa") + void shouldProperlyConvertToMetersFromMile() { + // Given + Thickness initialThicknessInMiles = Thickness.ofMiles(1.0); + + // When + Thickness actualInMeters = initialThicknessInMiles.toBaseUnit(); + Thickness actualInMiles = actualInMeters.toUnit(DistanceUnits.MILE); + double actualInMilesVal = actualInMeters.getInMiles(); + + // Then + Thickness expectedInMeters = Thickness.ofMeters(1609.344); + assertThat(actualInMiles.getValue()).isEqualTo(actualInMilesVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInMiles).isEqualTo(initialThicknessInMiles); + } + + @Test + @DisplayName("Thickness: should convert to m from ft and vice versa") + void shouldProperlyConvertToMetersFromFeet() { + // Given + Thickness initialThicknessInFeet = Thickness.ofFeet(10.0); + + // When + Thickness actualInMeters = initialThicknessInFeet.toBaseUnit(); + Thickness actualInFeet = actualInMeters.toUnit(DistanceUnits.FEET); + double actualInFeetVal = actualInMeters.getInFeet(); + + // Then + Thickness expectedInMeters = Thickness.ofMeters(3.048); + assertThat(actualInFeet.getValue()).isEqualTo(actualInFeetVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInFeet).isEqualTo(initialThicknessInFeet); + } + + @Test + @DisplayName("Thickness: should convert to m from ft and vice versa") + void shouldProperlyConvertToMetersFromInch() { + // Given + Thickness initialThicknessInInch = Thickness.ofInches(10.0); + + // When + Thickness actualInMeters = initialThicknessInInch.toBaseUnit(); + Thickness actualInInch = actualInMeters.toUnit(DistanceUnits.INCH); + double actualInInchVal = actualInMeters.getInInches(); + + // Then + Thickness expectedInMeters = Thickness.ofMeters(0.254); + assertThat(actualInInch.getValue()).isEqualTo(actualInInchVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInInch).isEqualTo(initialThicknessInInch); + } + + @Test + @DisplayName("Thickness: should have m as base unit") + void shouldHaveMetersAsBaseUnit() { + // Given + DistanceUnit expectedBaseUnit = DistanceUnits.METER; + + // When + Thickness ThicknessInMiles = Thickness.ofMiles(10); + DistanceUnit actualBaseUnit = ThicknessInMiles.getUnit().getBaseUnit(); + + // Then + assertThat(actualBaseUnit).isEqualTo(expectedBaseUnit); + } + + @Test + @DisplayName("Thickness: should return valid result from to() and getIn() methods") + void shouldReturnValidResultFromToAndGetInMethods() { + // Given + Thickness expected = Thickness.ofMeters(10.1); + + // When + Thickness actual = expected.toMeter() + .toCentimeter() + .toMillimeter() + .toKilometer() + .toMile() + .toFeet() + .toInch() + .toMeter(); + + double actualValue = expected.getInMeters(); + + // Then + assertThat(actual).isEqualTo(expected); + assertThat(actualValue).isEqualTo(expected.getValue()); + } + + @Test + @DisplayName("Thickness: should convert to m from nmi and vice versa") + void shouldProperlyConvertToMetersFromNauticalMile() { + // Given + Thickness initialThicknessInMiles = Thickness.ofNauticalMiles(1.0); + + // When + Thickness actualInMeters = initialThicknessInMiles.toBaseUnit(); + Thickness actualInMiles = actualInMeters.toUnit(DistanceUnits.NAUTICAL_MILE); + double actualInMilesVal = actualInMeters.getInNauticalMiles(); + + // Then + Thickness expectedInMeters = Thickness.ofMeters(1852); + assertThat(actualInMiles.getValue()).isEqualTo(actualInMilesVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInMiles).isEqualTo(initialThicknessInMiles); + } + +} diff --git a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/hydraulic/AbsoluteRoughnessTest.java b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/hydraulic/AbsoluteRoughnessTest.java new file mode 100644 index 0000000..a058e93 --- /dev/null +++ b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/hydraulic/AbsoluteRoughnessTest.java @@ -0,0 +1,177 @@ +package com.synerset.unitility.unitsystem.hydraulic; + +import com.synerset.unitility.unitsystem.common.DistanceUnit; +import com.synerset.unitility.unitsystem.common.DistanceUnits; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class AbsoluteRoughnessTest { + + @Test + @DisplayName("AbsoluteRoughness: should convert to m from mm and vice versa") + void shouldProperlyConvertToMetersFromMillimeters() { + // Given + AbsoluteRoughness initialAbsoluteRoughnessInMillimeters = AbsoluteRoughness.ofMillimeters(1000.0); + + // When + AbsoluteRoughness actualInMeters = initialAbsoluteRoughnessInMillimeters.toUnit(DistanceUnits.METER); + double actualInMetersVal = actualInMeters.getInMeters(); + AbsoluteRoughness actualInMillimeters = actualInMeters.toUnit(DistanceUnits.MILLIMETER); + double actualInMillimetersVal = actualInMeters.getInMillimeters(); + + // Then + AbsoluteRoughness expectedInMeters = AbsoluteRoughness.ofMeters(1.0); + assertThat(actualInMeters.getValue()).isEqualTo(actualInMetersVal); + assertThat(actualInMillimeters.getValue()).isEqualTo(actualInMillimetersVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInMillimeters).isEqualTo(initialAbsoluteRoughnessInMillimeters); + } + + @Test + @DisplayName("AbsoluteRoughness: should convert to m from cm and vice versa") + void shouldProperlyConvertToMetersFromCentimeters() { + // Given + AbsoluteRoughness initialAbsoluteRoughnessInCentimeters = AbsoluteRoughness.ofCentimeters(100.0); + + // When + AbsoluteRoughness actualInMeters = initialAbsoluteRoughnessInCentimeters.toBaseUnit(); + AbsoluteRoughness actualInCentimeters = actualInMeters.toUnit(DistanceUnits.CENTIMETER); + double actualInCentimetersVal = actualInMeters.getInCentimeters(); + + // Then + AbsoluteRoughness expectedInMeters = AbsoluteRoughness.ofMeters(1.0); + assertThat(actualInCentimeters.getValue()).isEqualTo(actualInCentimetersVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInCentimeters).isEqualTo(initialAbsoluteRoughnessInCentimeters); + } + + @Test + @DisplayName("AbsoluteRoughness: should convert to m from km and vice versa") + void shouldProperlyConvertToMetersFromKilometers() { + // Given + AbsoluteRoughness initialAbsoluteRoughnessInKilometers = AbsoluteRoughness.ofKilometers(1.0); + + // When + AbsoluteRoughness actualInMeters = initialAbsoluteRoughnessInKilometers.toBaseUnit(); + AbsoluteRoughness actualInKilometers = actualInMeters.toUnit(DistanceUnits.KILOMETER); + double actualInKilometersVal = actualInMeters.getInKilometers(); + + // Then + AbsoluteRoughness expectedInMeters = AbsoluteRoughness.ofMeters(1000.0); + assertThat(actualInKilometers.getValue()).isEqualTo(actualInKilometersVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInKilometers).isEqualTo(initialAbsoluteRoughnessInKilometers); + } + + @Test + @DisplayName("AbsoluteRoughness: should convert to m from mi and vice versa") + void shouldProperlyConvertToMetersFromMile() { + // Given + AbsoluteRoughness initialAbsoluteRoughnessInMiles = AbsoluteRoughness.ofMiles(1.0); + + // When + AbsoluteRoughness actualInMeters = initialAbsoluteRoughnessInMiles.toBaseUnit(); + AbsoluteRoughness actualInMiles = actualInMeters.toUnit(DistanceUnits.MILE); + double actualInMilesVal = actualInMeters.getInMiles(); + + // Then + AbsoluteRoughness expectedInMeters = AbsoluteRoughness.ofMeters(1609.344); + assertThat(actualInMiles.getValue()).isEqualTo(actualInMilesVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInMiles).isEqualTo(initialAbsoluteRoughnessInMiles); + } + + @Test + @DisplayName("AbsoluteRoughness: should convert to m from ft and vice versa") + void shouldProperlyConvertToMetersFromFeet() { + // Given + AbsoluteRoughness initialAbsoluteRoughnessInFeet = AbsoluteRoughness.ofFeet(10.0); + + // When + AbsoluteRoughness actualInMeters = initialAbsoluteRoughnessInFeet.toBaseUnit(); + AbsoluteRoughness actualInFeet = actualInMeters.toUnit(DistanceUnits.FEET); + double actualInFeetVal = actualInMeters.getInFeet(); + + // Then + AbsoluteRoughness expectedInMeters = AbsoluteRoughness.ofMeters(3.048); + assertThat(actualInFeet.getValue()).isEqualTo(actualInFeetVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInFeet).isEqualTo(initialAbsoluteRoughnessInFeet); + } + + @Test + @DisplayName("AbsoluteRoughness: should convert to m from ft and vice versa") + void shouldProperlyConvertToMetersFromInch() { + // Given + AbsoluteRoughness initialAbsoluteRoughnessInInch = AbsoluteRoughness.ofInches(10.0); + + // When + AbsoluteRoughness actualInMeters = initialAbsoluteRoughnessInInch.toBaseUnit(); + AbsoluteRoughness actualInInch = actualInMeters.toUnit(DistanceUnits.INCH); + double actualInInchVal = actualInMeters.getInInches(); + + // Then + AbsoluteRoughness expectedInMeters = AbsoluteRoughness.ofMeters(0.254); + assertThat(actualInInch.getValue()).isEqualTo(actualInInchVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInInch).isEqualTo(initialAbsoluteRoughnessInInch); + } + + @Test + @DisplayName("AbsoluteRoughness: should have m as base unit") + void shouldHaveMetersAsBaseUnit() { + // Given + DistanceUnit expectedBaseUnit = DistanceUnits.METER; + + // When + AbsoluteRoughness AbsoluteRoughnessInMiles = AbsoluteRoughness.ofMiles(10); + DistanceUnit actualBaseUnit = AbsoluteRoughnessInMiles.getUnit().getBaseUnit(); + + // Then + assertThat(actualBaseUnit).isEqualTo(expectedBaseUnit); + } + + @Test + @DisplayName("AbsoluteRoughness: should return valid result from to() and getIn() methods") + void shouldReturnValidResultFromToAndGetInMethods() { + // Given + AbsoluteRoughness expected = AbsoluteRoughness.ofMeters(10.1); + + // When + AbsoluteRoughness actual = expected.toMeter() + .toCentimeter() + .toMillimeter() + .toKilometer() + .toMile() + .toFeet() + .toInch() + .toMeter(); + + double actualValue = expected.getInMeters(); + + // Then + assertThat(actual).isEqualTo(expected); + assertThat(actualValue).isEqualTo(expected.getValue()); + } + + @Test + @DisplayName("AbsoluteRoughness: should convert to m from nmi and vice versa") + void shouldProperlyConvertToMetersFromNauticalMile() { + // Given + AbsoluteRoughness initialAbsoluteRoughnessInMiles = AbsoluteRoughness.ofNauticalMiles(1.0); + + // When + AbsoluteRoughness actualInMeters = initialAbsoluteRoughnessInMiles.toBaseUnit(); + AbsoluteRoughness actualInMiles = actualInMeters.toUnit(DistanceUnits.NAUTICAL_MILE); + double actualInMilesVal = actualInMeters.getInNauticalMiles(); + + // Then + AbsoluteRoughness expectedInMeters = AbsoluteRoughness.ofMeters(1852); + assertThat(actualInMiles.getValue()).isEqualTo(actualInMilesVal); + assertThat(actualInMeters).isEqualTo(expectedInMeters); + assertThat(actualInMiles).isEqualTo(initialAbsoluteRoughnessInMiles); + } + +} 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 index b433310..ff8ddd8 100644 --- 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 @@ -26,7 +26,7 @@ void findAllSupportedQuantities_shouldFindAllSupportedQuantitiesAndAssociatedUni Set allSupportedQuantities = QUANTITY_REGISTRY.findAllSupportedQuantities(); // Then - assertThat(allSupportedQuantities).isNotNull().isNotEmpty().hasSize(47); + assertThat(allSupportedQuantities).isNotNull().isNotEmpty().hasSize(49); } @Test diff --git a/unitility-persistence/src/main/java/com/synerset/unitility/persistence/converter/plainsivalue/common/AbsoluteRoughnessPlainSiConverter.java b/unitility-persistence/src/main/java/com/synerset/unitility/persistence/converter/plainsivalue/common/AbsoluteRoughnessPlainSiConverter.java new file mode 100644 index 0000000..c669f34 --- /dev/null +++ b/unitility-persistence/src/main/java/com/synerset/unitility/persistence/converter/plainsivalue/common/AbsoluteRoughnessPlainSiConverter.java @@ -0,0 +1,25 @@ +package com.synerset.unitility.persistence.converter.plainsivalue.common; + +import com.synerset.unitility.unitsystem.common.DistanceUnit; +import com.synerset.unitility.unitsystem.hydraulic.AbsoluteRoughness; +import com.synerset.unitility.unitsystem.util.PhysicalQuantityParsingFactory; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter +public class AbsoluteRoughnessPlainSiConverter implements AttributeConverter { + + public static final DistanceUnit DEFAULT_SI_UNIT = PhysicalQuantityParsingFactory.getDefaultParsingFactory() + .getDefaultUnit(AbsoluteRoughness.class); + + @Override + public Double convertToDatabaseColumn(AbsoluteRoughness attribute) { + return attribute == null ? null : attribute.getInUnit(DEFAULT_SI_UNIT); + } + + @Override + public AbsoluteRoughness convertToEntityAttribute(Double dbData) { + return dbData == null ? null : AbsoluteRoughness.of(dbData, DEFAULT_SI_UNIT); + } + +} \ No newline at end of file diff --git a/unitility-persistence/src/main/java/com/synerset/unitility/persistence/converter/plainsivalue/common/ThicknessPlainSiConverter.java b/unitility-persistence/src/main/java/com/synerset/unitility/persistence/converter/plainsivalue/common/ThicknessPlainSiConverter.java new file mode 100644 index 0000000..4f78567 --- /dev/null +++ b/unitility-persistence/src/main/java/com/synerset/unitility/persistence/converter/plainsivalue/common/ThicknessPlainSiConverter.java @@ -0,0 +1,25 @@ +package com.synerset.unitility.persistence.converter.plainsivalue.common; + +import com.synerset.unitility.unitsystem.common.DistanceUnit; +import com.synerset.unitility.unitsystem.common.Thickness; +import com.synerset.unitility.unitsystem.util.PhysicalQuantityParsingFactory; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter +public class ThicknessPlainSiConverter implements AttributeConverter { + + public static final DistanceUnit DEFAULT_SI_UNIT = PhysicalQuantityParsingFactory.getDefaultParsingFactory() + .getDefaultUnit(Thickness.class); + + @Override + public Double convertToDatabaseColumn(Thickness attribute) { + return attribute == null ? null : attribute.getInUnit(DEFAULT_SI_UNIT); + } + + @Override + public Thickness convertToEntityAttribute(Double dbData) { + return dbData == null ? null : Thickness.of(dbData, DEFAULT_SI_UNIT); + } + +} \ No newline at end of file diff --git a/unitility-persistence/src/test/java/com/synerset/unitility/persistence/converter/plainsivalue/PlainSiConverterTest.java b/unitility-persistence/src/test/java/com/synerset/unitility/persistence/converter/plainsivalue/PlainSiConverterTest.java index 1d2061d..75d3139 100644 --- a/unitility-persistence/src/test/java/com/synerset/unitility/persistence/converter/plainsivalue/PlainSiConverterTest.java +++ b/unitility-persistence/src/test/java/com/synerset/unitility/persistence/converter/plainsivalue/PlainSiConverterTest.java @@ -253,6 +253,48 @@ void shouldSuccessfullyConvertPerimeterTest() { assertThat(actualQuantityFromDB.getInFeet()).isEqualTo(perimeter.getInFeet(), withPrecision(1E-11)); } + @Test + @DisplayName("Thickness Plain SI Converter: should successfully convert Thickness") + void shouldSuccessfullyConvertThicknessTest() { + // Given + Thickness thickness = Thickness.ofFeet(20.0); + DistanceUnit defaultConverterUnit = ThicknessPlainSiConverter.DEFAULT_SI_UNIT; + double expectedValueFromDB = thickness.getInUnit(defaultConverterUnit); + + ThicknessPlainSiConverter converter = new ThicknessPlainSiConverter(); + + // When + Double actualValueToBePersistedInDB = converter.convertToDatabaseColumn(thickness); + Thickness actualQuantityFromDB = converter.convertToEntityAttribute(expectedValueFromDB); + + // Then + assertThat(actualValueToBePersistedInDB).isNotNull(); + assertThat(actualValueToBePersistedInDB).isEqualTo(expectedValueFromDB, withPrecision(1E-11)); + + assertThat(actualQuantityFromDB.getInFeet()).isEqualTo(thickness.getInFeet(), withPrecision(1E-11)); + } + + @Test + @DisplayName("AbsoluteRoughness Plain SI Converter: should successfully convert AbsoluteRoughness") + void shouldSuccessfullyConvertAbsoluteRoughnessTest() { + // Given + AbsoluteRoughness absoluteRoughness = AbsoluteRoughness.ofFeet(20.0); + DistanceUnit defaultConverterUnit = AbsoluteRoughnessPlainSiConverter.DEFAULT_SI_UNIT; + double expectedValueFromDB = absoluteRoughness.getInUnit(defaultConverterUnit); + + AbsoluteRoughnessPlainSiConverter converter = new AbsoluteRoughnessPlainSiConverter(); + + // When + Double actualValueToBePersistedInDB = converter.convertToDatabaseColumn(absoluteRoughness); + AbsoluteRoughness actualQuantityFromDB = converter.convertToEntityAttribute(expectedValueFromDB); + + // Then + assertThat(actualValueToBePersistedInDB).isNotNull(); + assertThat(actualValueToBePersistedInDB).isEqualTo(expectedValueFromDB, withPrecision(1E-11)); + + assertThat(actualQuantityFromDB.getInFeet()).isEqualTo(absoluteRoughness.getInFeet(), withPrecision(1E-11)); + } + @Test @DisplayName("Mass Plain SI Converter: should successfully convert Mass") void shouldSuccessfullyConvertMassTest() { From a89a3dd58f18c39a67ac08a28a8c0c35c2b2ef52 Mon Sep 17 00:00:00 2001 From: Piotr Jazdzyk Date: Thu, 18 Sep 2025 18:55:27 +0200 Subject: [PATCH 3/3] SNSUNI-141: Add new velocity unit: ft/min --- pom.xml | 2 +- .../unitility/unitsystem/common/Velocity.java | 12 ++++++++++ .../unitsystem/common/VelocityUnits.java | 1 + .../unitsystem/common/VelocityTest.java | 22 +++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5e5d65b..110826c 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ - 2.12.0 + 2.11.1 17 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 0ab6bcb..9482a98 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 @@ -49,6 +49,10 @@ public static Velocity ofFeetPerSecond(double value) { return new Velocity(value, VelocityUnits.FEET_PER_SECOND); } + public static Velocity ofFeetPerMinute(double value) { + return new Velocity(value, VelocityUnits.FEET_PER_MINUTE); + } + public static Velocity ofMilesPerHour(double value) { return new Velocity(value, VelocityUnits.MILES_PER_HOUR); } @@ -121,6 +125,10 @@ public Velocity toFeetPerSecond() { return toUnit(VelocityUnits.FEET_PER_SECOND); } + public Velocity toFeetPerMinute() { + return toUnit(VelocityUnits.FEET_PER_MINUTE); + } + public Velocity toMilesPerHour() { return toUnit(VelocityUnits.MILES_PER_HOUR); } @@ -154,6 +162,10 @@ public double getInFeetPerSeconds() { return getInUnit(VelocityUnits.FEET_PER_SECOND); } + public double getInFeetPerMinutes() { + return getInUnit(VelocityUnits.FEET_PER_MINUTE); + } + public double getInMilesPerHours() { return getInUnit(VelocityUnits.MILES_PER_HOUR); } diff --git a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/VelocityUnits.java b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/VelocityUnits.java index ac1d3ce..887cee0 100644 --- a/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/VelocityUnits.java +++ b/unitility-core/src/main/java/com/synerset/unitility/unitsystem/common/VelocityUnits.java @@ -12,6 +12,7 @@ public enum VelocityUnits implements VelocityUnit { KILOMETER_PER_HOUR("km/h", val -> val / 3.6, val -> val * 3.6), INCH_PER_SECOND("in/s", val -> val * 0.0254, val -> val / 0.0254), FEET_PER_SECOND("ft/s", val -> val * 0.3048, val -> val / 0.3048), + FEET_PER_MINUTE("ft/min", val -> val * 0.00508, val -> val / 0.00508), MILES_PER_HOUR("mph", val -> val * 0.44704, val -> val / 0.44704), KNOT("kn", val -> val * 0.514444444444444, val -> val / 0.514444444444444), MACH("Mach", val -> val * 340.29, val -> val / 340.29); diff --git a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/VelocityTest.java b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/VelocityTest.java index ce9f04d..02154c5 100644 --- a/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/VelocityTest.java +++ b/unitility-core/src/test/java/com/synerset/unitility/unitsystem/common/VelocityTest.java @@ -82,6 +82,28 @@ void shouldProperlyConvertMetersPerSecondToFeetPerSecond() { assertThat(actualInMetersPerSecond).isEqualTo(initialVelocity); } + @Test + @DisplayName("should convert m/s to ft/min and vice versa") + void shouldProperlyConvertMetersPerSecondToFeetPerMinute() { + // Given + Velocity initialVelocity = Velocity.ofMetersPerSecond(10.0); + + // When + Velocity actualInFeetPerMinute = initialVelocity.toUnit(VelocityUnits.FEET_PER_MINUTE); + double actualInFeetPerMinuteVal = initialVelocity.getInFeetPerMinutes(); + Velocity actualInMetersPerSecond = actualInFeetPerMinute.toBaseUnit(); + + // Then + // 10 m/s = 10 * 196.8503937 ≈ 1968.503937 ft/min + Velocity expectedInFeetPerMinute = Velocity.ofFeetPerMinute(1968.503937007874); + + assertThat(actualInFeetPerMinute.getValue()).isEqualTo(actualInFeetPerMinuteVal); + assertThat(actualInFeetPerMinute.getValue()) + .isEqualTo(expectedInFeetPerMinute.getValue(), withPrecision(1e-12)); + assertThat(actualInMetersPerSecond).isEqualTo(initialVelocity); + } + + @Test @DisplayName("should convert m/s to mph and vice versa") void shouldProperlyConvertMetersPerSecondToMilesPerHour() {