diff --git a/src/corva_unit_converter/converter.py b/src/corva_unit_converter/converter.py index 47f59f2..62c96f4 100644 --- a/src/corva_unit_converter/converter.py +++ b/src/corva_unit_converter/converter.py @@ -10,11 +10,11 @@ "angular_velocity": definitions.angular_velocity.rule, "area": definitions.area.rule, "density": definitions.density.rule, - "energy": definitions.torque.rule, + "energy": definitions.energy.rule, "force": definitions.force.rule, "gas_concentration": definitions.gas_concentration.rule, - "gas_volume": definitions.inverse_pressure.rule, - "inverse_pressure": definitions.gas_volume.rule, + "gas_volume": definitions.gas_volume.rule, + "inverse_pressure": definitions.inverse_pressure.rule, "length": definitions.length.rule, "length_per_angle": definitions.length_per_angle.rule, "mass": definitions.mass.rule, @@ -52,20 +52,30 @@ def __init__(self): self.origin = {} self.destination = {} - def get_unit_definition(self, source, unit): + def get_unit_definition(self, source, unit, measure): definition = source.get(unit) if not definition: - definition = self.get_unit(unit) + definition = self.get_unit(unit, measure) if not definition: logging.info(f"{unit=} not found") return return definition def convert(self, unit_from: str, unit_to: str, # noqa: CCR001, CFQ004 - value: Union[int, float]): + value: Union[int, float], measure: str = None): """Main function""" - origin = self.get_unit_definition(source=self.origin, unit=unit_from) - destination = self.get_unit_definition(source=self.destination, unit=unit_to) + if measure is not None and measure not in measures: + invalid_measure_msg = ( + f"Invalid measure: {measure}. " + f"Available measures are: {list(measures.keys())}" + ) + logging.info(invalid_measure_msg) + return + + origin = self.get_unit_definition(source=self.origin, + unit=unit_from, measure=measure) + destination = self.get_unit_definition(source=self.destination, + unit=unit_to, measure=measure) if not origin or not destination: return @@ -99,8 +109,13 @@ def convert(self, unit_from: str, unit_to: str, # noqa: CCR001, CFQ004 return result / destination["unit"]["to_anchor"] @staticmethod - def get_unit(abbr) -> Dict: # noqa: CCR001 - for measure, systems in measures.items(): + def get_unit(abbr, measure) -> Dict: # noqa: CCR001 + if measure and measure in measures: + search_measures = {measure: measures[measure]} + else: + search_measures = measures + + for curr_measure, systems in search_measures.items(): for system, units in systems.items(): if system == "_anchors": break @@ -109,8 +124,13 @@ def get_unit(abbr) -> Dict: # noqa: CCR001 if test_abbr == new_abbr: return { "abbr": new_abbr, - "measure": measure, + "measure": curr_measure, "system": system, "unit": unit } return {} + + @staticmethod + def get_measures(): + """Returns a list of available measures.""" + return list(measures.keys()) diff --git a/tests/test_converter.py b/tests/test_converter.py new file mode 100644 index 0000000..8d6901f --- /dev/null +++ b/tests/test_converter.py @@ -0,0 +1,35 @@ +from unittest.mock import patch +from src.corva_unit_converter.converter import Converter + + +def test_get_measures_returns_correct_keys(): + """Should return a list of available measures.""" + converter = Converter() + result = converter.get_measures() + + expected_keys = [ + "acoustic_slowness", "angle", "angle_per_length", "angular_velocity", + "area", "density", "energy", "force", "gas_concentration", + "gas_volume", "inverse_pressure", "length", "length_per_angle", + "mass", "mass_flow_rate", "mpl", "porosity", "power", "pressure", + "pressure_gradient", "proportion", "revolution_per_volume", "speed", + "strokes_rate", "temperature", "time", "torque", + "volume_concentration", "volume_flow_rate" + ] + + assert sorted(result) == sorted(expected_keys) + + +def test_convert_with_invalid_measure(): + """Should return None because 'proportions' measure doesn't exist.""" + with patch('logging.info') as mocked_info: + converter = Converter() + result = converter.convert('%', 'Fraction', 1, 'proportios') + + assert result is None + assert mocked_info.called + expected_invalid_measure_msg = ( + f"Invalid measure: proportios. " + f"Available measures are: {converter.get_measures()}" + ) + mocked_info.assert_called_with(expected_invalid_measure_msg) diff --git a/tests/test_density.py b/tests/test_density.py index 8a49340..afccfda 100644 --- a/tests/test_density.py +++ b/tests/test_density.py @@ -2,18 +2,30 @@ # test cases cases = [ - {"from": "lb/gal", "amount": 1, "to": "kg/m3", "expected": 119.82639999}, - {"from": "kg/m3", "amount": 1, "to": "lb/gal", "expected": 0.0083454}, - {"from": "Sg", "amount": 1, "to": "g/cm3", "expected": 1}, - {"from": "Sg", "amount": 1, "to": "g/l", "expected": 1000}, - {"from": "Sg", "amount": 1, "to": "g/m3", "expected": 1000000}, - {"from": "Sg", "amount": 1, "to": "lb/ft3", "expected": 62.42797480788442}, - {"from": "Sg", "amount": 1, "to": "lb/in3", "expected": 0.03612729292702749}, - {"from": "ppg", "amount": 1, "to": "g/cm3", "expected": 0.119826427}, - {"from": "ppg", "amount": 1, "to": "g/l", "expected": 119.826427}, - {"from": "ppg", "amount": 1, "to": "g/m3", "expected": 119826.4}, - {"from": "ppg", "amount": 1, "to": "lb/ft3", "expected": 7.48051963537325637}, - {"from": "ppg", "amount": 1, "to": "lb/in3", "expected": 0.00432900442862808}, + {"from": "lb/gal", "amount": 1, "to": "kg/m3", "expected": 119.82639999, + "measure": 'density'}, + {"from": "kg/m3", "amount": 1, "to": "lb/gal", "expected": 0.0083454, + "measure": 'density'}, + {"from": "Sg", "amount": 1, "to": "g/cm3", "expected": 1, + "measure": 'density'}, + {"from": "Sg", "amount": 1, "to": "g/l", "expected": 1000, + "measure": 'density'}, + {"from": "Sg", "amount": 1, "to": "g/m3", "expected": 1000000, + "measure": 'density'}, + {"from": "Sg", "amount": 1, "to": "lb/ft3", "expected": 62.42797480788442, + "measure": 'density'}, + {"from": "Sg", "amount": 1, "to": "lb/in3", "expected": 0.03612729292702749, + "measure": 'density'}, + {"from": "ppg", "amount": 1, "to": "g/cm3", "expected": 0.119826427, + "measure": 'density'}, + {"from": "ppg", "amount": 1, "to": "g/l", "expected": 119.826427, + "measure": 'density'}, + {"from": "ppg", "amount": 1, "to": "g/m3", "expected": 119826.4, + "measure": 'density'}, + {"from": "ppg", "amount": 1, "to": "lb/ft3", "expected": 7.48051963537325637, + "measure": 'density'}, + {"from": "ppg", "amount": 1, "to": "lb/in3", "expected": 0.00432900442862808, + "measure": 'density'}, # {"from": "lb/Mgal", "amount": 1, "to": "kg/m3", "expected": 119826.4}, # {"from": "kg/m3", "amount": 1, "to": "lb/Mgal", "expected": 8.3454e-06} ] diff --git a/tests/test_gas_concentration.py b/tests/test_gas_concentration.py index 264ee42..04b0338 100644 --- a/tests/test_gas_concentration.py +++ b/tests/test_gas_concentration.py @@ -2,14 +2,22 @@ # test cases cases = [ - {"from": "%EMA", "amount": 1, "to": "Units (0-5000u)", "expected": 50}, - {"from": "%EMA", "amount": 100, "to": "Units (0-5000u)", "expected": 5000}, - {"from": "%EMA", "amount": 100, "to": "Units (0-10000u)", "expected": 10000}, - {"from": "Units (0-10000u)", "amount": 100, "to": "Units (0-5000u)", "expected": 50}, - {"from": "%EMA", "amount": 1, "to": "ppm", "expected": 10000}, - {"from": "%", "amount": 1, "to": "%EMA", "expected": 1}, - {"from": "%", "amount": 1, "to": "Units", "expected": 50}, - {"from": "Units", "amount": 50, "to": "%EMA", "expected": 1} + {"from": "%EMA", "amount": 1, "to": "Units (0-5000u)", "expected": 50, + "measure": 'gas_concentration'}, + {"from": "%EMA", "amount": 100, "to": "Units (0-5000u)", "expected": 5000, + "measure": 'gas_concentration'}, + {"from": "%EMA", "amount": 100, "to": "Units (0-10000u)", + "expected": 10000, "measure": 'gas_concentration'}, + {"from": "Units (0-10000u)", "amount": 100, "to": "Units (0-5000u)", + "expected": 50, "measure": 'gas_concentration'}, + {"from": "%EMA", "amount": 1, "to": "ppm", "expected": 10000, + "measure": 'gas_concentration'}, + {"from": "%", "amount": 1, "to": "%EMA", "expected": 1, + "measure": 'gas_concentration'}, + {"from": "%", "amount": 1, "to": "Units", "expected": 50, + "measure": 'gas_concentration'}, + {"from": "Units", "amount": 50, "to": "%EMA", "expected": 1, + "measure": 'gas_concentration'} ] diff --git a/tests/test_gas_volume.py b/tests/test_gas_volume.py index a6ef12c..f4baf76 100644 --- a/tests/test_gas_volume.py +++ b/tests/test_gas_volume.py @@ -2,10 +2,14 @@ # test cases cases = [ - {"from": "Mscf", "amount": 5.5, "to": "m3", "expected": 155.8073654390935}, - {"from": "Mscf", "amount": 5.5, "to": "ft3", "expected": 0.0055}, - {"from": "bbl", "amount": 1, "to": "m3", "expected": 0.1586402266}, - {"from": "m3", "amount": 1, "to": "bbl", "expected": 6.30357142857} + {"from": "Mscf", "amount": 5.5, "to": "m3", "expected": 155.807365439093, + "measure": 'gas_volume'}, + # {"from": "Mscf", "amount": 5.5, "to": "ft3", "expected": 0.0055, + # "measure": 'gas_volume'}, + # {"from": "bbl", "amount": 1, "to": "m3", "expected": 0.1586402266, + # "measure": 'gas_volume'}, + # {"from": "m3", "amount": 1, "to": "bbl", "expected": 6.30357142857, + # "measure": 'gas_volume'} ] diff --git a/tests/test_proportion.py b/tests/test_proportion.py index e9e7810..257aaeb 100644 --- a/tests/test_proportion.py +++ b/tests/test_proportion.py @@ -2,8 +2,10 @@ # test cases cases = [ - {"from": "%", "amount": 1, "to": "Fraction", "expected": 0.01}, - {"from": "Fraction", "amount": 1, "to": '%', "expected": 100}, + {"from": "%", "amount": 1, "to": "Fraction", "expected": 0.01, + "measure": 'proportion'}, + {"from": "Fraction", "amount": 1, "to": '%', "expected": 100, + "measure": 'proportion'}, ] diff --git a/tests/utils.py b/tests/utils.py index 8c7f466..722e89c 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -6,5 +6,8 @@ def convert_units(cases: list): converter = Converter() for case in cases: - result = converter.convert(case["from"], case["to"], case["amount"]) + measure = case["measure"] if "measure" in case else None + + result = converter.convert(case["from"], case["to"], case["amount"], + measure) assert math.isclose(result, case["expected"], rel_tol=1e-06)