From 7aa7b08ef9557c463ed1270072ff37e2232ec606 Mon Sep 17 00:00:00 2001 From: JohnVonNeumann Date: Sat, 8 Jun 2024 12:30:07 +1000 Subject: [PATCH] FORMAT tests - run black to format package --- tests/assurance/test_assurance.py | 30 +- .../test_biogenic_accounting_methodology.py | 12 +- .../carbon_footprint/test_carbon_footprint.py | 597 +++++++++++++----- .../test_characterization_factors.py | 8 +- .../test_cross_sectoral_standard.py | 10 +- tests/carbon_footprint/test_declared_unit.py | 14 +- .../test_geographical_scope.py | 44 +- ...roduct_or_sector_specific_rule_operator.py | 8 +- .../test_region_or_subregion.py | 47 +- .../test_data_model_extension.py | 83 ++- .../test_data_quality_indicators.py | 61 +- .../test_data_quality_rating.py | 4 +- .../product_footprint/test_company_id_list.py | 55 +- tests/product_footprint/test_cpc.py | 89 +-- tests/product_footprint/test_id.py | 2 +- .../test_product_footprint.py | 359 ++++++++--- .../product_footprint/test_product_id_list.py | 80 ++- .../product_footprint/test_validity_period.py | 2 +- tests/test_datetime.py | 24 +- tests/test_urn.py | 34 +- 20 files changed, 1130 insertions(+), 433 deletions(-) diff --git a/tests/assurance/test_assurance.py b/tests/assurance/test_assurance.py index 0db003a..2ee3a83 100644 --- a/tests/assurance/test_assurance.py +++ b/tests/assurance/test_assurance.py @@ -1,7 +1,10 @@ import pytest from pathfinder_framework.assurance.assurance import ( - Assurance, Coverage, Level, Boundary + Assurance, + Coverage, + Level, + Boundary, ) from pathfinder_framework.datetime import DateTime @@ -13,7 +16,15 @@ def test_assurance_init(): def test_assurance_to_dict(): - assurance = Assurance(True, "My Auditor", Coverage.PCF_SYSTEM, Level.LIMITED, Boundary.CRADLE_TO_GATE, DateTime("2022-12-08T14:47:32Z"), "ISO 14044") + assurance = Assurance( + True, + "My Auditor", + Coverage.PCF_SYSTEM, + Level.LIMITED, + Boundary.CRADLE_TO_GATE, + DateTime("2022-12-08T14:47:32Z"), + "ISO 14044", + ) expected_dict = { "assurance": True, "provider_name": "My Auditor", @@ -21,7 +32,7 @@ def test_assurance_to_dict(): "level": "limited", "boundary": "Cradle-to-Gate", "completed_at": "2022-12-08T14:47:32Z", - "standard_name": "ISO 14044" + "standard_name": "ISO 14044", } assert assurance.to_dict() == expected_dict @@ -62,7 +73,13 @@ def test_assurance_init_with_invalid_boundary(): def test_assurance_init_with_valid_enum_values(): - assurance = Assurance(True, "My Auditor", coverage=Coverage.PCF_SYSTEM, level=Level.LIMITED, boundary=Boundary.GATE_TO_GATE) + assurance = Assurance( + True, + "My Auditor", + coverage=Coverage.PCF_SYSTEM, + level=Level.LIMITED, + boundary=Boundary.GATE_TO_GATE, + ) assert assurance.coverage == Coverage.PCF_SYSTEM assert assurance.level == Level.LIMITED assert assurance.boundary == Boundary.GATE_TO_GATE @@ -92,7 +109,10 @@ def test_assurance_init_with_invalid_provider_name(provider_name): assert str(excinfo.value) == "provider_name must be a string" -@pytest.mark.parametrize("completed_at", [DateTime("2022-12-08T14:47:32Z"), DateTime("2023-01-01T00:00:00Z"), None]) +@pytest.mark.parametrize( + "completed_at", + [DateTime("2022-12-08T14:47:32Z"), DateTime("2023-01-01T00:00:00Z"), None], +) def test_assurance_init_with_valid_completed_at(completed_at): Assurance(True, "My Auditor", completed_at=completed_at) diff --git a/tests/carbon_footprint/test_biogenic_accounting_methodology.py b/tests/carbon_footprint/test_biogenic_accounting_methodology.py index 935af68..d120a43 100644 --- a/tests/carbon_footprint/test_biogenic_accounting_methodology.py +++ b/tests/carbon_footprint/test_biogenic_accounting_methodology.py @@ -1,13 +1,15 @@ import pytest -from pathfinder_framework.carbon_footprint.biogenic_accounting_methodology import BiogenicAccountingMethodology +from pathfinder_framework.carbon_footprint.biogenic_accounting_methodology import ( + BiogenicAccountingMethodology, +) def test_biogenic_accounting_methodology_values(): - assert BiogenicAccountingMethodology.PEF.value == 'PEF' - assert BiogenicAccountingMethodology.ISO.value == 'ISO' - assert BiogenicAccountingMethodology.GHGP.value == 'GHGP' - assert BiogenicAccountingMethodology.QUANTIS.value == 'Quantis' + assert BiogenicAccountingMethodology.PEF.value == "PEF" + assert BiogenicAccountingMethodology.ISO.value == "ISO" + assert BiogenicAccountingMethodology.GHGP.value == "GHGP" + assert BiogenicAccountingMethodology.QUANTIS.value == "Quantis" with pytest.raises(AttributeError): assert BiogenicAccountingMethodology.Invalid diff --git a/tests/carbon_footprint/test_carbon_footprint.py b/tests/carbon_footprint/test_carbon_footprint.py index 10d1d5a..644cd0c 100644 --- a/tests/carbon_footprint/test_carbon_footprint.py +++ b/tests/carbon_footprint/test_carbon_footprint.py @@ -1,18 +1,28 @@ import pytest from pathfinder_framework.assurance.assurance import ( - Assurance, Coverage, Level, Boundary + Assurance, + Coverage, + Level, + Boundary, ) from pathfinder_framework.carbon_footprint.carbon_footprint import CarbonFootprint -from pathfinder_framework.carbon_footprint.characterization_factors import CharacterizationFactors -from pathfinder_framework.carbon_footprint.cross_sectoral_standard import CrossSectoralStandard +from pathfinder_framework.carbon_footprint.characterization_factors import ( + CharacterizationFactors, +) +from pathfinder_framework.carbon_footprint.cross_sectoral_standard import ( + CrossSectoralStandard, +) from pathfinder_framework.carbon_footprint.declared_unit import DeclaredUnit from pathfinder_framework.datetime import DateTime from pathfinder_framework.carbon_footprint.reference_period import ReferencePeriod from pathfinder_framework.carbon_footprint.geographical_scope import ( - CarbonFootprintGeographicalScope, GeographicalGranularity + CarbonFootprintGeographicalScope, + GeographicalGranularity, +) +from pathfinder_framework.data_quality_indicators.data_quality_indicators import ( + DataQualityIndicators, ) -from pathfinder_framework.data_quality_indicators.data_quality_indicators import DataQualityIndicators @pytest.fixture @@ -32,9 +42,16 @@ def valid_carbon_footprint_data(): "exempted_emissions_percent": 1.0, "reference_period": ReferencePeriod(start=DateTime.now(), end=DateTime.now()), "packaging_emissions_included": True, - "geographical_scope": CarbonFootprintGeographicalScope(global_scope=True, geography_country_subdivision=None, geography_country=None, geography_region_or_subregion=None), + "geographical_scope": CarbonFootprintGeographicalScope( + global_scope=True, + geography_country_subdivision=None, + geography_country=None, + geography_region_or_subregion=None, + ), "primary_data_share": 50.0, - "dqi": DataQualityIndicators(reference_period=ReferencePeriod(start=DateTime.now(), end=DateTime.now())), + "dqi": DataQualityIndicators( + reference_period=ReferencePeriod(start=DateTime.now(), end=DateTime.now()) + ), "d_luc_ghg_emissions": 2, "land_management_ghg_emissions": 1.0, "other_biogenic_ghg_emissions": 1.5, @@ -53,7 +70,7 @@ def valid_carbon_footprint_data(): completed_at=DateTime.now(), standard_name="Example standard name", comments="Example comments", - ) + ), } @@ -68,49 +85,123 @@ def test_carbon_footprint_instantiation(valid_carbon_footprint_data): def test_carbon_footprint_attributes(valid_carbon_footprint_data): carbon_footprint = CarbonFootprint(**valid_carbon_footprint_data) - assert carbon_footprint.declared_unit == valid_carbon_footprint_data["declared_unit"] - assert carbon_footprint.unitary_product_amount == valid_carbon_footprint_data["unitary_product_amount"] - assert carbon_footprint.p_cf_excluding_biogenic == valid_carbon_footprint_data["p_cf_excluding_biogenic"] - assert carbon_footprint.p_cf_including_biogenic == valid_carbon_footprint_data["p_cf_including_biogenic"] - assert carbon_footprint.fossil_ghg_emissions == valid_carbon_footprint_data["fossil_ghg_emissions"] - assert carbon_footprint.fossil_carbon_content == valid_carbon_footprint_data["fossil_carbon_content"] - assert carbon_footprint.biogenic_carbon_content == valid_carbon_footprint_data["biogenic_carbon_content"] - assert carbon_footprint.characterization_factors == valid_carbon_footprint_data["characterization_factors"] - assert carbon_footprint.ipcc_characterization_factors_sources == valid_carbon_footprint_data["ipcc_characterization_factors_sources"] - assert carbon_footprint.cross_sectoral_standards_used == valid_carbon_footprint_data["cross_sectoral_standards_used"] - assert carbon_footprint.boundary_processes_description == valid_carbon_footprint_data["boundary_processes_description"] - assert carbon_footprint.exempted_emissions_percent == valid_carbon_footprint_data["exempted_emissions_percent"] + assert ( + carbon_footprint.declared_unit == valid_carbon_footprint_data["declared_unit"] + ) + assert ( + carbon_footprint.unitary_product_amount + == valid_carbon_footprint_data["unitary_product_amount"] + ) + assert ( + carbon_footprint.p_cf_excluding_biogenic + == valid_carbon_footprint_data["p_cf_excluding_biogenic"] + ) + assert ( + carbon_footprint.p_cf_including_biogenic + == valid_carbon_footprint_data["p_cf_including_biogenic"] + ) + assert ( + carbon_footprint.fossil_ghg_emissions + == valid_carbon_footprint_data["fossil_ghg_emissions"] + ) + assert ( + carbon_footprint.fossil_carbon_content + == valid_carbon_footprint_data["fossil_carbon_content"] + ) + assert ( + carbon_footprint.biogenic_carbon_content + == valid_carbon_footprint_data["biogenic_carbon_content"] + ) + assert ( + carbon_footprint.characterization_factors + == valid_carbon_footprint_data["characterization_factors"] + ) + assert ( + carbon_footprint.ipcc_characterization_factors_sources + == valid_carbon_footprint_data["ipcc_characterization_factors_sources"] + ) + assert ( + carbon_footprint.cross_sectoral_standards_used + == valid_carbon_footprint_data["cross_sectoral_standards_used"] + ) + assert ( + carbon_footprint.boundary_processes_description + == valid_carbon_footprint_data["boundary_processes_description"] + ) + assert ( + carbon_footprint.exempted_emissions_percent + == valid_carbon_footprint_data["exempted_emissions_percent"] + ) assert isinstance(carbon_footprint.reference_period, ReferencePeriod) - assert carbon_footprint.packaging_emissions_included == valid_carbon_footprint_data["packaging_emissions_included"] - assert isinstance(carbon_footprint.geographical_scope, CarbonFootprintGeographicalScope) + assert ( + carbon_footprint.packaging_emissions_included + == valid_carbon_footprint_data["packaging_emissions_included"] + ) + assert isinstance( + carbon_footprint.geographical_scope, CarbonFootprintGeographicalScope + ) assert isinstance(carbon_footprint.dqi, DataQualityIndicators) - assert carbon_footprint.d_luc_ghg_emissions == valid_carbon_footprint_data["d_luc_ghg_emissions"] - assert carbon_footprint.land_management_ghg_emissions == valid_carbon_footprint_data["land_management_ghg_emissions"] - assert carbon_footprint.other_biogenic_ghg_emissions == valid_carbon_footprint_data["other_biogenic_ghg_emissions"] - assert carbon_footprint.biogenic_carbon_withdrawal == valid_carbon_footprint_data["biogenic_carbon_withdrawal"] - assert carbon_footprint.iluc_ghg_emissions == valid_carbon_footprint_data["iluc_ghg_emissions"] - assert carbon_footprint.aircraft_ghg_emissions == valid_carbon_footprint_data["aircraft_ghg_emissions"] - assert carbon_footprint.packaging_ghg_emissions == valid_carbon_footprint_data["packaging_ghg_emissions"] - assert carbon_footprint.allocation_rules_description == valid_carbon_footprint_data["allocation_rules_description"] - assert carbon_footprint.uncertainty_assessment_description == valid_carbon_footprint_data["uncertainty_assessment_description"] + assert ( + carbon_footprint.d_luc_ghg_emissions + == valid_carbon_footprint_data["d_luc_ghg_emissions"] + ) + assert ( + carbon_footprint.land_management_ghg_emissions + == valid_carbon_footprint_data["land_management_ghg_emissions"] + ) + assert ( + carbon_footprint.other_biogenic_ghg_emissions + == valid_carbon_footprint_data["other_biogenic_ghg_emissions"] + ) + assert ( + carbon_footprint.biogenic_carbon_withdrawal + == valid_carbon_footprint_data["biogenic_carbon_withdrawal"] + ) + assert ( + carbon_footprint.iluc_ghg_emissions + == valid_carbon_footprint_data["iluc_ghg_emissions"] + ) + assert ( + carbon_footprint.aircraft_ghg_emissions + == valid_carbon_footprint_data["aircraft_ghg_emissions"] + ) + assert ( + carbon_footprint.packaging_ghg_emissions + == valid_carbon_footprint_data["packaging_ghg_emissions"] + ) + assert ( + carbon_footprint.allocation_rules_description + == valid_carbon_footprint_data["allocation_rules_description"] + ) + assert ( + carbon_footprint.uncertainty_assessment_description + == valid_carbon_footprint_data["uncertainty_assessment_description"] + ) assert isinstance(carbon_footprint.assurance, Assurance) def test_carbon_footprint_invalid_declared_unit(valid_carbon_footprint_data): invalid_data = {**valid_carbon_footprint_data, "declared_unit": "invalid unit"} - with pytest.raises(ValueError, match="declared_unit 'invalid unit' is not valid. It must be one of the following: liter, kilogram, cubic meter, kilowatt hour, megajoule, ton kilometer, square meter"): + with pytest.raises( + ValueError, + match="declared_unit 'invalid unit' is not valid. It must be one of the following: liter, kilogram, cubic meter, kilowatt hour, megajoule, ton kilometer, square meter", + ): CarbonFootprint(**invalid_data) def test_carbon_footprint_invalid_unitary_product_amount(valid_carbon_footprint_data): invalid_data = {**valid_carbon_footprint_data, "unitary_product_amount": 0.0} - with pytest.raises(ValueError, match="unitary_product_amount must be strictly greater than 0"): + with pytest.raises( + ValueError, match="unitary_product_amount must be strictly greater than 0" + ): CarbonFootprint(**invalid_data) def test_carbon_footprint_invalid_p_cf_excluding_biogenic(valid_carbon_footprint_data): invalid_data = {**valid_carbon_footprint_data, "p_cf_excluding_biogenic": -0.5} - with pytest.raises(ValueError, match="p_cf_excluding_biogenic must be equal to or greater than 0"): + with pytest.raises( + ValueError, match="p_cf_excluding_biogenic must be equal to or greater than 0" + ): CarbonFootprint(**invalid_data) @@ -119,7 +210,9 @@ def test_carbon_footprint_invalid_fossil_ghg_emissions(valid_carbon_footprint_da invalid_data["fossil_ghg_emissions"] = -0.3 with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) - assert str(excinfo.value) == "fossil_ghg_emissions must be equal to or greater than 0" + assert ( + str(excinfo.value) == "fossil_ghg_emissions must be equal to or greater than 0" + ) def test_carbon_footprint_invalid_fossil_carbon_content(valid_carbon_footprint_data): @@ -127,7 +220,9 @@ def test_carbon_footprint_invalid_fossil_carbon_content(valid_carbon_footprint_d invalid_data["fossil_carbon_content"] = -0.2 with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) - assert str(excinfo.value) == "fossil_carbon_content must be equal to or greater than 0" + assert ( + str(excinfo.value) == "fossil_carbon_content must be equal to or greater than 0" + ) def test_carbon_footprint_invalid_biogenic_carbon_content(valid_carbon_footprint_data): @@ -135,7 +230,10 @@ def test_carbon_footprint_invalid_biogenic_carbon_content(valid_carbon_footprint invalid_data["biogenic_carbon_content"] = -0.1 with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) - assert str(excinfo.value) == "biogenic_carbon_content must be equal to or greater than 0" + assert ( + str(excinfo.value) + == "biogenic_carbon_content must be equal to or greater than 0" + ) def test_carbon_footprint_invalid_characterization_factors(valid_carbon_footprint_data): @@ -143,26 +241,40 @@ def test_carbon_footprint_invalid_characterization_factors(valid_carbon_footprin invalid_data["characterization_factors"] = "AR7" with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) - assert str(excinfo.value) == "characterization_factors must be an instance of CharacterizationFactors" + assert ( + str(excinfo.value) + == "characterization_factors must be an instance of CharacterizationFactors" + ) -def test_carbon_footprint_invalid_ipcc_characterization_factors_sources(valid_carbon_footprint_data): +def test_carbon_footprint_invalid_ipcc_characterization_factors_sources( + valid_carbon_footprint_data, +): invalid_data = valid_carbon_footprint_data.copy() invalid_data["ipcc_characterization_factors_sources"] = [] with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) - assert str(excinfo.value) == "ipcc_characterization_factors_sources must not be empty" + assert ( + str(excinfo.value) == "ipcc_characterization_factors_sources must not be empty" + ) -def test_carbon_footprint_invalid_cross_sectoral_standards_used(valid_carbon_footprint_data): +def test_carbon_footprint_invalid_cross_sectoral_standards_used( + valid_carbon_footprint_data, +): invalid_data = valid_carbon_footprint_data.copy() invalid_data["cross_sectoral_standards_used"] = ["invalid standard"] with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) - assert str(excinfo.value) == "cross_sectoral_standards_used must be a list of CrossSectoralStandard" + assert ( + str(excinfo.value) + == "cross_sectoral_standards_used must be a list of CrossSectoralStandard" + ) -def test_carbon_footprint_invalid_boundary_processes_description(valid_carbon_footprint_data): +def test_carbon_footprint_invalid_boundary_processes_description( + valid_carbon_footprint_data, +): invalid_data = valid_carbon_footprint_data.copy() invalid_data["boundary_processes_description"] = "" with pytest.raises(ValueError) as excinfo: @@ -170,12 +282,16 @@ def test_carbon_footprint_invalid_boundary_processes_description(valid_carbon_fo assert str(excinfo.value) == "boundary_processes_description must not be empty" -def test_carbon_footprint_invalid_exempted_emissions_percent(valid_carbon_footprint_data): +def test_carbon_footprint_invalid_exempted_emissions_percent( + valid_carbon_footprint_data, +): invalid_data = valid_carbon_footprint_data.copy() invalid_data["exempted_emissions_percent"] = 6.0 with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) - assert str(excinfo.value) == "exempted_emissions_percent must be between 0.0 and 5.0" + assert ( + str(excinfo.value) == "exempted_emissions_percent must be between 0.0 and 5.0" + ) def test_carbon_footprint_invalid_reference_period(valid_carbon_footprint_data): @@ -183,10 +299,14 @@ def test_carbon_footprint_invalid_reference_period(valid_carbon_footprint_data): invalid_data["reference_period"] = "invalid reference period" with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) - assert str(excinfo.value) == "reference_period must be an instance of ReferencePeriod" + assert ( + str(excinfo.value) == "reference_period must be an instance of ReferencePeriod" + ) -def test_carbon_footprint_invalid_packaging_emissions_included(valid_carbon_footprint_data): +def test_carbon_footprint_invalid_packaging_emissions_included( + valid_carbon_footprint_data, +): invalid_data = valid_carbon_footprint_data.copy() invalid_data["packaging_emissions_included"] = "not a boolean" with pytest.raises(ValueError) as excinfo: @@ -194,116 +314,192 @@ def test_carbon_footprint_invalid_packaging_emissions_included(valid_carbon_foot assert str(excinfo.value) == "packaging_emissions_included must be a boolean" -def test_carbon_footprint_valid_packaging_emissions_included(valid_carbon_footprint_data): +def test_carbon_footprint_valid_packaging_emissions_included( + valid_carbon_footprint_data, +): carbon_footprint = CarbonFootprint(**valid_carbon_footprint_data) assert carbon_footprint.packaging_emissions_included is True -@pytest.mark.parametrize("attribute, value", [ - ("p_cf_including_biogenic", 1.0), - ("d_luc_ghg_emissions", 1.0), - ("land_management_ghg_emissions", 1.0), - ("other_biogenic_ghg_emissions", 1.5), - ("biogenic_carbon_withdrawal", -1.0) -]) -def test_carbon_footprint_valid_attribute(valid_carbon_footprint_data, attribute, value): +@pytest.mark.parametrize( + "attribute, value", + [ + ("p_cf_including_biogenic", 1.0), + ("d_luc_ghg_emissions", 1.0), + ("land_management_ghg_emissions", 1.0), + ("other_biogenic_ghg_emissions", 1.5), + ("biogenic_carbon_withdrawal", -1.0), + ], +) +def test_carbon_footprint_valid_attribute( + valid_carbon_footprint_data, attribute, value +): valid_carbon_footprint_data[attribute] = value carbon_footprint = CarbonFootprint(**valid_carbon_footprint_data) assert getattr(carbon_footprint, attribute) == value -@pytest.mark.parametrize("attribute, value, expected_error", [ - ("p_cf_including_biogenic", "not a number", "p_cf_including_biogenic must be a number"), - ("d_luc_ghg_emissions", "not a number", "d_luc_ghg_emissions must be a non-negative number"), - ("land_management_ghg_emissions", "not a number", "land_management_ghg_emissions must be a number"), - ("other_biogenic_ghg_emissions", "not a number", "other_biogenic_ghg_emissions must be a non-negative number"), - ("other_biogenic_ghg_emissions", -1, "other_biogenic_ghg_emissions must be a non-negative number"), - ("biogenic_carbon_withdrawal", "not a number", "biogenic_carbon_withdrawal must be a non-positive number"), - ("biogenic_carbon_withdrawal", 1, "biogenic_carbon_withdrawal must be a non-positive number") -]) -def test_carbon_footprint_invalid_attribute_type(valid_carbon_footprint_data, attribute, value, expected_error): +@pytest.mark.parametrize( + "attribute, value, expected_error", + [ + ( + "p_cf_including_biogenic", + "not a number", + "p_cf_including_biogenic must be a number", + ), + ( + "d_luc_ghg_emissions", + "not a number", + "d_luc_ghg_emissions must be a non-negative number", + ), + ( + "land_management_ghg_emissions", + "not a number", + "land_management_ghg_emissions must be a number", + ), + ( + "other_biogenic_ghg_emissions", + "not a number", + "other_biogenic_ghg_emissions must be a non-negative number", + ), + ( + "other_biogenic_ghg_emissions", + -1, + "other_biogenic_ghg_emissions must be a non-negative number", + ), + ( + "biogenic_carbon_withdrawal", + "not a number", + "biogenic_carbon_withdrawal must be a non-positive number", + ), + ( + "biogenic_carbon_withdrawal", + 1, + "biogenic_carbon_withdrawal must be a non-positive number", + ), + ], +) +def test_carbon_footprint_invalid_attribute_type( + valid_carbon_footprint_data, attribute, value, expected_error +): valid_carbon_footprint_data[attribute] = value with pytest.raises(ValueError) as excinfo: CarbonFootprint(**valid_carbon_footprint_data) assert str(excinfo.value) == expected_error -@pytest.mark.parametrize("attribute", [ - "p_cf_including_biogenic", - "d_luc_ghg_emissions", - "land_management_ghg_emissions", - "other_biogenic_ghg_emissions", - "biogenic_carbon_withdrawal" -]) -def test_carbon_footprint_attribute_optional_before_2025(valid_carbon_footprint_data, attribute): +@pytest.mark.parametrize( + "attribute", + [ + "p_cf_including_biogenic", + "d_luc_ghg_emissions", + "land_management_ghg_emissions", + "other_biogenic_ghg_emissions", + "biogenic_carbon_withdrawal", + ], +) +def test_carbon_footprint_attribute_optional_before_2025( + valid_carbon_footprint_data, attribute +): del valid_carbon_footprint_data[attribute] - valid_carbon_footprint_data["reference_period"] = ReferencePeriod(start=DateTime("2024-01-01T00:00:00Z"), end=DateTime("2024-12-31T00:00:00Z")) + valid_carbon_footprint_data["reference_period"] = ReferencePeriod( + start=DateTime("2024-01-01T00:00:00Z"), end=DateTime("2024-12-31T00:00:00Z") + ) carbon_footprint = CarbonFootprint(**valid_carbon_footprint_data) assert getattr(carbon_footprint, attribute) is None -@pytest.mark.parametrize("attribute", [ - "p_cf_including_biogenic", - "d_luc_ghg_emissions", - "land_management_ghg_emissions", - "other_biogenic_ghg_emissions", - "biogenic_carbon_withdrawal" -]) -def test_carbon_footprint_missing_attributes_valid_before_2025(valid_carbon_footprint_data, attribute): +@pytest.mark.parametrize( + "attribute", + [ + "p_cf_including_biogenic", + "d_luc_ghg_emissions", + "land_management_ghg_emissions", + "other_biogenic_ghg_emissions", + "biogenic_carbon_withdrawal", + ], +) +def test_carbon_footprint_missing_attributes_valid_before_2025( + valid_carbon_footprint_data, attribute +): if hasattr(valid_carbon_footprint_data, attribute): delattr(valid_carbon_footprint_data, attribute) - valid_carbon_footprint_data["reference_period"] = ReferencePeriod(start=DateTime("2024-01-01T00:00:00Z"), end=DateTime("2024-12-31T00:00:00Z")) + valid_carbon_footprint_data["reference_period"] = ReferencePeriod( + start=DateTime("2024-01-01T00:00:00Z"), end=DateTime("2024-12-31T00:00:00Z") + ) carbon_footprint = CarbonFootprint(**valid_carbon_footprint_data) -@pytest.mark.parametrize("attribute", [ - "p_cf_including_biogenic", - "d_luc_ghg_emissions", - "land_management_ghg_emissions", - "other_biogenic_ghg_emissions", - "biogenic_carbon_withdrawal" -]) -def test_carbon_footprint_missing_attributes_invalid_after_2025(valid_carbon_footprint_data, attribute): +@pytest.mark.parametrize( + "attribute", + [ + "p_cf_including_biogenic", + "d_luc_ghg_emissions", + "land_management_ghg_emissions", + "other_biogenic_ghg_emissions", + "biogenic_carbon_withdrawal", + ], +) +def test_carbon_footprint_missing_attributes_invalid_after_2025( + valid_carbon_footprint_data, attribute +): del valid_carbon_footprint_data[attribute] - valid_carbon_footprint_data["reference_period"] = ReferencePeriod(start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z")) + valid_carbon_footprint_data["reference_period"] = ReferencePeriod( + start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z") + ) with pytest.raises(ValueError): CarbonFootprint(**valid_carbon_footprint_data) def test_primary_data_share_optional_before_2025(valid_carbon_footprint_data): - valid_carbon_footprint_data["reference_period"] = ReferencePeriod(start=DateTime("2024-01-01T00:00:00Z"), end=DateTime("2024-12-31T00:00:00Z")) + valid_carbon_footprint_data["reference_period"] = ReferencePeriod( + start=DateTime("2024-01-01T00:00:00Z"), end=DateTime("2024-12-31T00:00:00Z") + ) valid_carbon_footprint_data["primary_data_share"] = None carbon_footprint = CarbonFootprint(**valid_carbon_footprint_data) def test_primary_data_share_required_after_2025(valid_carbon_footprint_data): - valid_carbon_footprint_data["reference_period"] = ReferencePeriod(start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z")) + valid_carbon_footprint_data["reference_period"] = ReferencePeriod( + start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z") + ) valid_carbon_footprint_data["primary_data_share"] = None - with pytest.raises(ValueError, match="Attribute 'primary_data_share' must be defined"): + with pytest.raises( + ValueError, match="Attribute 'primary_data_share' must be defined" + ): CarbonFootprint(**valid_carbon_footprint_data) def test_dqi_optional_before_2025(valid_carbon_footprint_data): - valid_carbon_footprint_data["reference_period"] = ReferencePeriod(start=DateTime("2024-01-01T00:00:00Z"), end=DateTime("2024-12-31T00:00:00Z")) + valid_carbon_footprint_data["reference_period"] = ReferencePeriod( + start=DateTime("2024-01-01T00:00:00Z"), end=DateTime("2024-12-31T00:00:00Z") + ) valid_carbon_footprint_data["dqi"] = None carbon_footprint = CarbonFootprint(**valid_carbon_footprint_data) def test_dqi_required_after_2025(valid_carbon_footprint_data): - valid_carbon_footprint_data["reference_period"] = ReferencePeriod(start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z")) + valid_carbon_footprint_data["reference_period"] = ReferencePeriod( + start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z") + ) valid_carbon_footprint_data["dqi"] = None with pytest.raises(ValueError, match="Attribute 'dqi' must be defined"): CarbonFootprint(**valid_carbon_footprint_data) def test_primary_data_share_or_dqi_required_before_2025(valid_carbon_footprint_data): - valid_carbon_footprint_data["reference_period"] = ReferencePeriod(start=DateTime("2024-01-01T00:00:00Z"), end=DateTime("2024-12-31T00:00:00Z")) + valid_carbon_footprint_data["reference_period"] = ReferencePeriod( + start=DateTime("2024-01-01T00:00:00Z"), end=DateTime("2024-12-31T00:00:00Z") + ) valid_carbon_footprint_data["primary_data_share"] = None valid_carbon_footprint_data["dqi"] = None - with pytest.raises(ValueError, match="At least one of 'primary_data_share' or 'dqi' must be defined"): + with pytest.raises( + ValueError, + match="At least one of 'primary_data_share' or 'dqi' must be defined", + ): CarbonFootprint(**valid_carbon_footprint_data) @@ -312,32 +508,47 @@ def test_carbon_footprint_invalid_geographical_scope_type(valid_carbon_footprint invalid_data["geographical_scope"] = "not a CarbonFootprintGeographicalScope" with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) - assert str(excinfo.value) == "geographical_scope must be an instance of CarbonFootprintGeographicalScope" + assert ( + str(excinfo.value) + == "geographical_scope must be an instance of CarbonFootprintGeographicalScope" + ) def test_carbon_footprint_valid_geographical_scope(valid_carbon_footprint_data): carbon_footprint = CarbonFootprint(**valid_carbon_footprint_data) - assert isinstance(carbon_footprint.geographical_scope, CarbonFootprintGeographicalScope) + assert isinstance( + carbon_footprint.geographical_scope, CarbonFootprintGeographicalScope + ) def test_carbon_footprint_geographical_scope_attributes(valid_carbon_footprint_data): carbon_footprint = CarbonFootprint(**valid_carbon_footprint_data) assert carbon_footprint.geographical_scope.scope == "Global" - assert carbon_footprint.geographical_scope.granularity == GeographicalGranularity.GLOBAL + assert ( + carbon_footprint.geographical_scope.granularity + == GeographicalGranularity.GLOBAL + ) @pytest.mark.parametrize("iluc_ghg_emissions", [None, 0, 1, 100, 0.0, 1.0, 100.0]) -def test_carbon_footprint_valid_iluc_ghg_emissions(valid_carbon_footprint_data, iluc_ghg_emissions): +def test_carbon_footprint_valid_iluc_ghg_emissions( + valid_carbon_footprint_data, iluc_ghg_emissions +): valid_data = valid_carbon_footprint_data.copy() valid_data["iluc_ghg_emissions"] = iluc_ghg_emissions CarbonFootprint(**valid_data) -@pytest.mark.parametrize("iluc_ghg_emissions, expected_error", [ - (-1.0, "iluc_ghg_emissions must be a non-negative number"), - ("not a number", "iluc_ghg_emissions must be a non-negative number"), -]) -def test_carbon_footprint_invalid_iluc_ghg_emissions(valid_carbon_footprint_data, iluc_ghg_emissions, expected_error): +@pytest.mark.parametrize( + "iluc_ghg_emissions, expected_error", + [ + (-1.0, "iluc_ghg_emissions must be a non-negative number"), + ("not a number", "iluc_ghg_emissions must be a non-negative number"), + ], +) +def test_carbon_footprint_invalid_iluc_ghg_emissions( + valid_carbon_footprint_data, iluc_ghg_emissions, expected_error +): invalid_data = valid_carbon_footprint_data.copy() invalid_data["iluc_ghg_emissions"] = iluc_ghg_emissions with pytest.raises(ValueError) as excinfo: @@ -346,17 +557,24 @@ def test_carbon_footprint_invalid_iluc_ghg_emissions(valid_carbon_footprint_data @pytest.mark.parametrize("aircraft_ghg_emissions", [None, 0, 1, 100, 0.0, 1.0, 100.0]) -def test_carbon_footprint_valid_aircraft_ghg_emissions(valid_carbon_footprint_data, aircraft_ghg_emissions): +def test_carbon_footprint_valid_aircraft_ghg_emissions( + valid_carbon_footprint_data, aircraft_ghg_emissions +): valid_data = valid_carbon_footprint_data.copy() valid_data["aircraft_ghg_emissions"] = aircraft_ghg_emissions CarbonFootprint(**valid_data) -@pytest.mark.parametrize("aircraft_ghg_emissions, expected_error", [ - (-1.0, "aircraft_ghg_emissions must be a non-negative number"), - ("not a number", "aircraft_ghg_emissions must be a non-negative number"), -]) -def test_carbon_footprint_invalid_aircraft_ghg_emissions(valid_carbon_footprint_data, aircraft_ghg_emissions, expected_error): +@pytest.mark.parametrize( + "aircraft_ghg_emissions, expected_error", + [ + (-1.0, "aircraft_ghg_emissions must be a non-negative number"), + ("not a number", "aircraft_ghg_emissions must be a non-negative number"), + ], +) +def test_carbon_footprint_invalid_aircraft_ghg_emissions( + valid_carbon_footprint_data, aircraft_ghg_emissions, expected_error +): invalid_data = valid_carbon_footprint_data.copy() invalid_data["aircraft_ghg_emissions"] = aircraft_ghg_emissions with pytest.raises(ValueError) as excinfo: @@ -364,25 +582,55 @@ def test_carbon_footprint_invalid_aircraft_ghg_emissions(valid_carbon_footprint_ assert str(excinfo.value) == expected_error -@pytest.mark.parametrize("packaging_ghg_emissions, packaging_emissions_included", [ - (0.0, True), - (1.0, True), - (100.0, True), - (None, False), -]) -def test_carbon_footprint_valid_packaging_ghg_emissions(valid_carbon_footprint_data, packaging_ghg_emissions, packaging_emissions_included): +@pytest.mark.parametrize( + "packaging_ghg_emissions, packaging_emissions_included", + [ + (0.0, True), + (1.0, True), + (100.0, True), + (None, False), + ], +) +def test_carbon_footprint_valid_packaging_ghg_emissions( + valid_carbon_footprint_data, packaging_ghg_emissions, packaging_emissions_included +): valid_data = valid_carbon_footprint_data.copy() valid_data["packaging_ghg_emissions"] = packaging_ghg_emissions valid_data["packaging_emissions_included"] = packaging_emissions_included CarbonFootprint(**valid_data) -@pytest.mark.parametrize("packaging_ghg_emissions, packaging_emissions_included, expected_error", [ - (-1.0, True, "packaging_ghg_emissions must be a non-negative number if packaging_emissions_included is true"), - ("not a number", True, "packaging_ghg_emissions must be a non-negative number if packaging_emissions_included is true"), - (1.0, False, "packaging_ghg_emissions must not be defined if packaging_emissions_included is false"), - (None, True, "packaging_ghg_emissions must be a non-negative number if packaging_emissions_included is true"), -]) -def test_carbon_footprint_invalid_packaging_ghg_emissions(valid_carbon_footprint_data, packaging_ghg_emissions, packaging_emissions_included, expected_error): + +@pytest.mark.parametrize( + "packaging_ghg_emissions, packaging_emissions_included, expected_error", + [ + ( + -1.0, + True, + "packaging_ghg_emissions must be a non-negative number if packaging_emissions_included is true", + ), + ( + "not a number", + True, + "packaging_ghg_emissions must be a non-negative number if packaging_emissions_included is true", + ), + ( + 1.0, + False, + "packaging_ghg_emissions must not be defined if packaging_emissions_included is false", + ), + ( + None, + True, + "packaging_ghg_emissions must be a non-negative number if packaging_emissions_included is true", + ), + ], +) +def test_carbon_footprint_invalid_packaging_ghg_emissions( + valid_carbon_footprint_data, + packaging_ghg_emissions, + packaging_emissions_included, + expected_error, +): invalid_data = valid_carbon_footprint_data.copy() invalid_data["packaging_ghg_emissions"] = packaging_ghg_emissions invalid_data["packaging_emissions_included"] = packaging_emissions_included @@ -391,60 +639,95 @@ def test_carbon_footprint_invalid_packaging_ghg_emissions(valid_carbon_footprint assert str(excinfo.value) == expected_error -@pytest.mark.parametrize("allocation_rules_description", [None, "Example allocation rules description"]) -def test_carbon_footprint_valid_allocation_rules_description(valid_carbon_footprint_data, allocation_rules_description): +@pytest.mark.parametrize( + "allocation_rules_description", [None, "Example allocation rules description"] +) +def test_carbon_footprint_valid_allocation_rules_description( + valid_carbon_footprint_data, allocation_rules_description +): valid_data = valid_carbon_footprint_data.copy() valid_data["allocation_rules_description"] = allocation_rules_description CarbonFootprint(**valid_data) -@pytest.mark.parametrize("allocation_rules_description, expected_error", [ - (1, "allocation_rules_description must be a string"), -]) -def test_carbon_footprint_invalid_allocation_rules_description(valid_carbon_footprint_data, allocation_rules_description, expected_error): + +@pytest.mark.parametrize( + "allocation_rules_description, expected_error", + [ + (1, "allocation_rules_description must be a string"), + ], +) +def test_carbon_footprint_invalid_allocation_rules_description( + valid_carbon_footprint_data, allocation_rules_description, expected_error +): invalid_data = valid_carbon_footprint_data.copy() invalid_data["allocation_rules_description"] = allocation_rules_description with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) assert str(excinfo.value) == expected_error -@pytest.mark.parametrize("uncertainty_assessment_description", [None, "uncertainty assessment description"]) -def test_carbon_footprint_valid_uncertainty_assessment_description(valid_carbon_footprint_data, uncertainty_assessment_description): + +@pytest.mark.parametrize( + "uncertainty_assessment_description", [None, "uncertainty assessment description"] +) +def test_carbon_footprint_valid_uncertainty_assessment_description( + valid_carbon_footprint_data, uncertainty_assessment_description +): valid_data = valid_carbon_footprint_data.copy() - valid_data["uncertainty_assessment_description"] = uncertainty_assessment_description + valid_data["uncertainty_assessment_description"] = ( + uncertainty_assessment_description + ) CarbonFootprint(**valid_data) -@pytest.mark.parametrize("uncertainty_assessment_description, expected_error", [ - (1, "uncertainty_assessment_description must be a string"), -]) -def test_carbon_footprint_invalid_uncertainty_assessment_description(valid_carbon_footprint_data, uncertainty_assessment_description, expected_error): +@pytest.mark.parametrize( + "uncertainty_assessment_description, expected_error", + [ + (1, "uncertainty_assessment_description must be a string"), + ], +) +def test_carbon_footprint_invalid_uncertainty_assessment_description( + valid_carbon_footprint_data, uncertainty_assessment_description, expected_error +): invalid_data = valid_carbon_footprint_data.copy() - invalid_data["uncertainty_assessment_description"] = uncertainty_assessment_description + invalid_data["uncertainty_assessment_description"] = ( + uncertainty_assessment_description + ) with pytest.raises(ValueError) as excinfo: CarbonFootprint(**invalid_data) assert str(excinfo.value) == expected_error -@pytest.mark.parametrize("assurance", [None, Assurance( - assurance=True, - provider_name="Example provider name", - coverage=Coverage.PCF_SYSTEM, - level=Level.REASONABLE, - boundary=Boundary.GATE_TO_GATE, - completed_at=DateTime.now(), - standard_name="Example standard name", - comments="Example comments", -)]) +@pytest.mark.parametrize( + "assurance", + [ + None, + Assurance( + assurance=True, + provider_name="Example provider name", + coverage=Coverage.PCF_SYSTEM, + level=Level.REASONABLE, + boundary=Boundary.GATE_TO_GATE, + completed_at=DateTime.now(), + standard_name="Example standard name", + comments="Example comments", + ), + ], +) def test_carbon_footprint_valid_assurance(valid_carbon_footprint_data, assurance): valid_data = valid_carbon_footprint_data.copy() valid_data["assurance"] = assurance CarbonFootprint(**valid_data) -@pytest.mark.parametrize("assurance, expected_error", [ - (1, "assurance must be an instance of Assurance"), -]) -def test_carbon_footprint_invalid_assurance(valid_carbon_footprint_data, assurance, expected_error): +@pytest.mark.parametrize( + "assurance, expected_error", + [ + (1, "assurance must be an instance of Assurance"), + ], +) +def test_carbon_footprint_invalid_assurance( + valid_carbon_footprint_data, assurance, expected_error +): invalid_data = valid_carbon_footprint_data.copy() invalid_data["assurance"] = assurance with pytest.raises(ValueError) as excinfo: diff --git a/tests/carbon_footprint/test_characterization_factors.py b/tests/carbon_footprint/test_characterization_factors.py index 9eca5a1..d270c4e 100644 --- a/tests/carbon_footprint/test_characterization_factors.py +++ b/tests/carbon_footprint/test_characterization_factors.py @@ -1,11 +1,13 @@ import pytest -from pathfinder_framework.carbon_footprint.characterization_factors import CharacterizationFactors +from pathfinder_framework.carbon_footprint.characterization_factors import ( + CharacterizationFactors, +) def test_characterization_factors_values(): - assert CharacterizationFactors.AR5 == 'AR5' - assert CharacterizationFactors.AR6 == 'AR6' + assert CharacterizationFactors.AR5 == "AR5" + assert CharacterizationFactors.AR6 == "AR6" with pytest.raises(AttributeError): assert CharacterizationFactors.Invalid diff --git a/tests/carbon_footprint/test_cross_sectoral_standard.py b/tests/carbon_footprint/test_cross_sectoral_standard.py index 252a2d5..9f17f19 100644 --- a/tests/carbon_footprint/test_cross_sectoral_standard.py +++ b/tests/carbon_footprint/test_cross_sectoral_standard.py @@ -1,7 +1,9 @@ -from pathfinder_framework.carbon_footprint.cross_sectoral_standard import CrossSectoralStandard +from pathfinder_framework.carbon_footprint.cross_sectoral_standard import ( + CrossSectoralStandard, +) def test_cross_sectoral_standard_values(): - assert CrossSectoralStandard.GHG_PROTOCOL == 'GHG Protocol Product standard' - assert CrossSectoralStandard.ISO_14067 == 'ISO Standard 14067' - assert CrossSectoralStandard.ISO_14044 == 'ISO Standard 14044' + assert CrossSectoralStandard.GHG_PROTOCOL == "GHG Protocol Product standard" + assert CrossSectoralStandard.ISO_14067 == "ISO Standard 14067" + assert CrossSectoralStandard.ISO_14044 == "ISO Standard 14044" diff --git a/tests/carbon_footprint/test_declared_unit.py b/tests/carbon_footprint/test_declared_unit.py index 7dffc49..7313105 100644 --- a/tests/carbon_footprint/test_declared_unit.py +++ b/tests/carbon_footprint/test_declared_unit.py @@ -2,10 +2,10 @@ def test_declared_unit_values(): - assert DeclaredUnit.LITER == 'liter' - assert DeclaredUnit.KILOGRAM == 'kilogram' - assert DeclaredUnit.CUBIC_METER == 'cubic meter' - assert DeclaredUnit.KILOWATT_HOUR == 'kilowatt hour' - assert DeclaredUnit.MEGAJOULE == 'megajoule' - assert DeclaredUnit.TON_KILOMETER == 'ton kilometer' - assert DeclaredUnit.SQUARE_METER == 'square meter' + assert DeclaredUnit.LITER == "liter" + assert DeclaredUnit.KILOGRAM == "kilogram" + assert DeclaredUnit.CUBIC_METER == "cubic meter" + assert DeclaredUnit.KILOWATT_HOUR == "kilowatt hour" + assert DeclaredUnit.MEGAJOULE == "megajoule" + assert DeclaredUnit.TON_KILOMETER == "ton kilometer" + assert DeclaredUnit.SQUARE_METER == "square meter" diff --git a/tests/carbon_footprint/test_geographical_scope.py b/tests/carbon_footprint/test_geographical_scope.py index 874cb4a..229c70b 100644 --- a/tests/carbon_footprint/test_geographical_scope.py +++ b/tests/carbon_footprint/test_geographical_scope.py @@ -1,6 +1,9 @@ import pytest -from pathfinder_framework.carbon_footprint.geographical_scope import CarbonFootprintGeographicalScope, GeographicalGranularity +from pathfinder_framework.carbon_footprint.geographical_scope import ( + CarbonFootprintGeographicalScope, + GeographicalGranularity, +) from pathfinder_framework.carbon_footprint.region_or_subregion import RegionOrSubregion @@ -14,7 +17,10 @@ ], ) def test_carbon_footprint_geographical_scope_successful_instantiation( - global_scope, geography_country_subdivision, geography_country, geography_region_or_subregion + global_scope, + geography_country_subdivision, + geography_country, + geography_region_or_subregion, ): CarbonFootprintGeographicalScope( global_scope=global_scope, @@ -34,7 +40,11 @@ def test_carbon_footprint_geographical_scope_successful_instantiation( ], ) def test_carbon_footprint_geographical_scope_failed_instantiation( - global_scope, geography_country_subdivision, geography_country, geography_region_or_subregion, expected_error + global_scope, + geography_country_subdivision, + geography_country, + geography_region_or_subregion, + expected_error, ): with pytest.raises(expected_error): CarbonFootprintGeographicalScope( @@ -61,7 +71,9 @@ def test_geography_country_scope(): def test_geography_region_or_subregion_scope(): - scope = CarbonFootprintGeographicalScope(geography_region_or_subregion=RegionOrSubregion.AFRICA) + scope = CarbonFootprintGeographicalScope( + geography_region_or_subregion=RegionOrSubregion.AFRICA + ) assert scope.scope == RegionOrSubregion.AFRICA @@ -81,7 +93,9 @@ def test_geography_country_scope_granularity(): def test_geography_region_or_subregion_scope_granularity(): - scope = CarbonFootprintGeographicalScope(geography_region_or_subregion=RegionOrSubregion.AFRICA) + scope = CarbonFootprintGeographicalScope( + geography_region_or_subregion=RegionOrSubregion.AFRICA + ) assert scope.granularity == GeographicalGranularity.REGION_OR_SUBREGION @@ -105,22 +119,30 @@ def test_carbon_footprint_geographical_scope_invalid_country_codes(country_code) CarbonFootprintGeographicalScope(geography_country=country_code) -@pytest.mark.parametrize("subdivision_code", ["US-CA", "FR-IDF", "GB-ENG", "CN-SH", "JP-13"]) +@pytest.mark.parametrize( + "subdivision_code", ["US-CA", "FR-IDF", "GB-ENG", "CN-SH", "JP-13"] +) def test_carbon_footprint_geographical_scope_valid_subdivision_codes(subdivision_code): - scope = CarbonFootprintGeographicalScope(geography_country_subdivision=subdivision_code) + scope = CarbonFootprintGeographicalScope( + geography_country_subdivision=subdivision_code + ) assert scope.granularity == GeographicalGranularity.COUNTRY_SUBDIVISION assert scope.scope == subdivision_code -@pytest.mark.parametrize("subdivision_code", ["US-XX", "FR-ABC", "GB-123", "CN-11", "CN-", "JP- ", None]) -def test_carbon_footprint_geographical_scope_invalid_subdivision_codes(subdivision_code): +@pytest.mark.parametrize( + "subdivision_code", ["US-XX", "FR-ABC", "GB-123", "CN-11", "CN-", "JP- ", None] +) +def test_carbon_footprint_geographical_scope_invalid_subdivision_codes( + subdivision_code, +): with pytest.raises(ValueError): CarbonFootprintGeographicalScope(geography_country_subdivision=subdivision_code) def test_no_scope_raises_value_error(): with pytest.raises( - ValueError, - match="At least one argument must be provided from: global_scope, geography_country_subdivision, geography_country, or geography_region_or_subregion" + ValueError, + match="At least one argument must be provided from: global_scope, geography_country_subdivision, geography_country, or geography_region_or_subregion", ): CarbonFootprintGeographicalScope() diff --git a/tests/carbon_footprint/test_product_or_sector_specific_rule_operator.py b/tests/carbon_footprint/test_product_or_sector_specific_rule_operator.py index 9307f51..6478a1c 100644 --- a/tests/carbon_footprint/test_product_or_sector_specific_rule_operator.py +++ b/tests/carbon_footprint/test_product_or_sector_specific_rule_operator.py @@ -1,9 +1,9 @@ from pathfinder_framework.carbon_footprint.product_or_sector_specific_rule_operator import ( - ProductOrSectorSpecificRuleOperator + ProductOrSectorSpecificRuleOperator, ) def test_product_or_sector_specific_rule_operator_values(): - assert ProductOrSectorSpecificRuleOperator.PEF == 'PEF' - assert ProductOrSectorSpecificRuleOperator.EPD_INTERNATIONAL == 'EPD International' - assert ProductOrSectorSpecificRuleOperator.OTHER == 'Other' + assert ProductOrSectorSpecificRuleOperator.PEF == "PEF" + assert ProductOrSectorSpecificRuleOperator.EPD_INTERNATIONAL == "EPD International" + assert ProductOrSectorSpecificRuleOperator.OTHER == "Other" diff --git a/tests/carbon_footprint/test_region_or_subregion.py b/tests/carbon_footprint/test_region_or_subregion.py index ca50a6e..773e115 100644 --- a/tests/carbon_footprint/test_region_or_subregion.py +++ b/tests/carbon_footprint/test_region_or_subregion.py @@ -2,25 +2,28 @@ def test_region_or_subregion_values(): - assert RegionOrSubregion.AFRICA == 'Africa' - assert RegionOrSubregion.AMERICAS == 'Americas' - assert RegionOrSubregion.ASIA == 'Asia' - assert RegionOrSubregion.EUROPE == 'Europe' - assert RegionOrSubregion.OCEANIA == 'Oceania' - assert RegionOrSubregion.AUSTRALIA_AND_NEW_ZEALAND == 'Australia and New Zealand' - assert RegionOrSubregion.CENTRAL_ASIA == 'Central Asia' - assert RegionOrSubregion.EASTERN_ASIA == 'Eastern Asia' - assert RegionOrSubregion.EASTERN_EUROPE == 'Eastern Europe' - assert RegionOrSubregion.LATIN_AMERICA_AND_THE_CARIBBEAN == 'Latin America and the Caribbean' - assert RegionOrSubregion.MELANESIA == 'Melanesia' - assert RegionOrSubregion.MICRONESIA == 'Micronesia' - assert RegionOrSubregion.NORTHERN_AFRICA == 'Northern Africa' - assert RegionOrSubregion.NORTHERN_AMERICA == 'Northern America' - assert RegionOrSubregion.NORTHERN_EUROPE == 'Northern Europe' - assert RegionOrSubregion.POLYNESIA == 'Polynesia' - assert RegionOrSubregion.SOUTH_EASTERN_ASIA == 'South-eastern Asia' - assert RegionOrSubregion.SOUTHERN_ASIA == 'Southern Asia' - assert RegionOrSubregion.SOUTHERN_EUROPE == 'Southern Europe' - assert RegionOrSubregion.SUB_SAHARAN_AFRICA == 'Sub-Saharan Africa' - assert RegionOrSubregion.WESTERN_ASIA == 'Western Asia' - assert RegionOrSubregion.WESTERN_EUROPE == 'Western Europe' + assert RegionOrSubregion.AFRICA == "Africa" + assert RegionOrSubregion.AMERICAS == "Americas" + assert RegionOrSubregion.ASIA == "Asia" + assert RegionOrSubregion.EUROPE == "Europe" + assert RegionOrSubregion.OCEANIA == "Oceania" + assert RegionOrSubregion.AUSTRALIA_AND_NEW_ZEALAND == "Australia and New Zealand" + assert RegionOrSubregion.CENTRAL_ASIA == "Central Asia" + assert RegionOrSubregion.EASTERN_ASIA == "Eastern Asia" + assert RegionOrSubregion.EASTERN_EUROPE == "Eastern Europe" + assert ( + RegionOrSubregion.LATIN_AMERICA_AND_THE_CARIBBEAN + == "Latin America and the Caribbean" + ) + assert RegionOrSubregion.MELANESIA == "Melanesia" + assert RegionOrSubregion.MICRONESIA == "Micronesia" + assert RegionOrSubregion.NORTHERN_AFRICA == "Northern Africa" + assert RegionOrSubregion.NORTHERN_AMERICA == "Northern America" + assert RegionOrSubregion.NORTHERN_EUROPE == "Northern Europe" + assert RegionOrSubregion.POLYNESIA == "Polynesia" + assert RegionOrSubregion.SOUTH_EASTERN_ASIA == "South-eastern Asia" + assert RegionOrSubregion.SOUTHERN_ASIA == "Southern Asia" + assert RegionOrSubregion.SOUTHERN_EUROPE == "Southern Europe" + assert RegionOrSubregion.SUB_SAHARAN_AFRICA == "Sub-Saharan Africa" + assert RegionOrSubregion.WESTERN_ASIA == "Western Asia" + assert RegionOrSubregion.WESTERN_EUROPE == "Western Europe" diff --git a/tests/data_model_extension/test_data_model_extension.py b/tests/data_model_extension/test_data_model_extension.py index f62b800..9750d5d 100644 --- a/tests/data_model_extension/test_data_model_extension.py +++ b/tests/data_model_extension/test_data_model_extension.py @@ -1,6 +1,8 @@ import pytest -from pathfinder_framework.data_model_extension.data_model_extension import DataModelExtension +from pathfinder_framework.data_model_extension.data_model_extension import ( + DataModelExtension, +) @pytest.fixture @@ -9,7 +11,7 @@ def valid_data_model_extension(): "spec_version": "2.0.0", "data_schema": "https://catalog.carbon-transparency.com/shipment/1.0.0/schema.json", "data": {"shipmentId": "S1234567890", "consignmentId": "Cabc.def-ghi"}, - "documentation": "https://catalog.carbon-transparency.com/shipment/1.0.0/documentation.html" + "documentation": "https://catalog.carbon-transparency.com/shipment/1.0.0/documentation.html", } @@ -18,14 +20,21 @@ def test_data_model_extension_init_valid_spec_version(valid_data_model_extension assert data_model_extension.spec_version == "2.0.0" -def test_data_model_extension_init_invalid_spec_version_major(valid_data_model_extension): - invalid_data_model_extension = {**valid_data_model_extension, "spec_version": "1.0.0"} +def test_data_model_extension_init_invalid_spec_version_major( + valid_data_model_extension, +): + invalid_data_model_extension = { + **valid_data_model_extension, + "spec_version": "1.0.0", + } with pytest.raises(ValueError, match="Invalid spec version"): DataModelExtension(**invalid_data_model_extension) @pytest.mark.parametrize("spec_version", ["2.1.0", "2.0.1", "invalid"]) -def test_data_model_extension_init_invalid_spec_version(valid_data_model_extension, spec_version): +def test_data_model_extension_init_invalid_spec_version( + valid_data_model_extension, spec_version +): invalid_data = {**valid_data_model_extension, "spec_version": spec_version} with pytest.raises(ValueError, match="Invalid spec version"): DataModelExtension(**invalid_data) @@ -33,24 +42,40 @@ def test_data_model_extension_init_invalid_spec_version(valid_data_model_extensi def test_data_model_extension_init_valid_data_schema(valid_data_model_extension): data_model_extension = DataModelExtension(**valid_data_model_extension) - assert data_model_extension.data_schema == "https://catalog.carbon-transparency.com/shipment/1.0.0/schema.json" - - -def test_data_model_extension_init_invalid_data_schema_scheme(valid_data_model_extension): - invalid_data = {**valid_data_model_extension, "data_schema": "http://catalog.carbon-transparency.com/shipment/1.0.0/schema.json"} + assert ( + data_model_extension.data_schema + == "https://catalog.carbon-transparency.com/shipment/1.0.0/schema.json" + ) + + +def test_data_model_extension_init_invalid_data_schema_scheme( + valid_data_model_extension, +): + invalid_data = { + **valid_data_model_extension, + "data_schema": "http://catalog.carbon-transparency.com/shipment/1.0.0/schema.json", + } with pytest.raises(ValueError, match="Invalid data schema URL scheme"): DataModelExtension(**invalid_data) -def test_data_model_extension_init_invalid_data_schema_netloc(valid_data_model_extension): - invalid_data = {**valid_data_model_extension, "data_schema": "https:///shipment/1.0.0/schema.json"} +def test_data_model_extension_init_invalid_data_schema_netloc( + valid_data_model_extension, +): + invalid_data = { + **valid_data_model_extension, + "data_schema": "https:///shipment/1.0.0/schema.json", + } with pytest.raises(ValueError, match="Invalid data schema URL"): DataModelExtension(**invalid_data) def test_data_model_extension_init_valid_data(valid_data_model_extension): data_model_extension = DataModelExtension(**valid_data_model_extension) - assert data_model_extension.data == {"shipmentId": "S1234567890", "consignmentId": "Cabc.def-ghi"} + assert data_model_extension.data == { + "shipmentId": "S1234567890", + "consignmentId": "Cabc.def-ghi", + } def test_data_model_extension_init_invalid_data_type(valid_data_model_extension): @@ -67,17 +92,30 @@ def test_data_model_extension_init_invalid_data_format(valid_data_model_extensio def test_data_model_extension_init_valid_documentation(valid_data_model_extension): data_model_extension = DataModelExtension(**valid_data_model_extension) - assert data_model_extension.documentation == "https://catalog.carbon-transparency.com/shipment/1.0.0/documentation.html" - - -def test_data_model_extension_init_invalid_documentation_scheme(valid_data_model_extension): - invalid_data = {**valid_data_model_extension, "documentation": "http://catalog.carbon-transparency.com/shipment/1.0.0/documentation.html"} + assert ( + data_model_extension.documentation + == "https://catalog.carbon-transparency.com/shipment/1.0.0/documentation.html" + ) + + +def test_data_model_extension_init_invalid_documentation_scheme( + valid_data_model_extension, +): + invalid_data = { + **valid_data_model_extension, + "documentation": "http://catalog.carbon-transparency.com/shipment/1.0.0/documentation.html", + } with pytest.raises(ValueError, match="Invalid documentation URL scheme"): DataModelExtension(**invalid_data) -def test_data_model_extension_init_invalid_documentation_netloc(valid_data_model_extension): - invalid_data = {**valid_data_model_extension, "documentation": "https:///shipment/1.0.0/documentation.html"} +def test_data_model_extension_init_invalid_documentation_netloc( + valid_data_model_extension, +): + invalid_data = { + **valid_data_model_extension, + "documentation": "https:///shipment/1.0.0/documentation.html", + } with pytest.raises(ValueError, match="Invalid documentation URL"): DataModelExtension(**invalid_data) @@ -93,8 +131,9 @@ def test_data_model_extension_neq(valid_data_model_extension): data_model_extension2 = DataModelExtension( **{ **valid_data_model_extension, - "data_schema": "https://zerotwentyfifty.com/extension/1.0.0/schema.json" - }) + "data_schema": "https://zerotwentyfifty.com/extension/1.0.0/schema.json", + } + ) assert data_model_extension1 != data_model_extension2 diff --git a/tests/data_quality_indicators/test_data_quality_indicators.py b/tests/data_quality_indicators/test_data_quality_indicators.py index f0436a2..0a39d7e 100644 --- a/tests/data_quality_indicators/test_data_quality_indicators.py +++ b/tests/data_quality_indicators/test_data_quality_indicators.py @@ -1,47 +1,74 @@ import pytest from pathfinder_framework.carbon_footprint.reference_period import ReferencePeriod -from pathfinder_framework.data_quality_indicators.data_quality_indicators import DataQualityIndicators -from pathfinder_framework.data_quality_indicators.data_quality_rating import DataQualityRating +from pathfinder_framework.data_quality_indicators.data_quality_indicators import ( + DataQualityIndicators, +) +from pathfinder_framework.data_quality_indicators.data_quality_rating import ( + DataQualityRating, +) from pathfinder_framework.datetime import DateTime @pytest.fixture def valid_data(): return { - "reference_period": ReferencePeriod(start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z")), + "reference_period": ReferencePeriod( + start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z") + ), "coverage_percent": 80.0, "technological_dqr": DataQualityRating(2), "temporal_dqr": DataQualityRating(2), "geographical_dqr": DataQualityRating(1), "completeness_dqr": DataQualityRating(2), - "reliability_dqr": DataQualityRating(3) + "reliability_dqr": DataQualityRating(3), } @pytest.mark.parametrize( "missing_attribute", - ["coverage_percent", "technological_dqr", "temporal_dqr", "geographical_dqr", "completeness_dqr", "reliability_dqr"] + [ + "coverage_percent", + "technological_dqr", + "temporal_dqr", + "geographical_dqr", + "completeness_dqr", + "reliability_dqr", + ], ) def test_dqi_missing_attributes_after_2025(valid_data, missing_attribute): del valid_data[missing_attribute] with pytest.raises(ValueError) as excinfo: DataQualityIndicators(**valid_data) - assert str(excinfo.value) == f"Attribute '{missing_attribute}' must be defined and not None for reporting periods including 2025 or later" + assert ( + str(excinfo.value) + == f"Attribute '{missing_attribute}' must be defined and not None for reporting periods including 2025 or later" + ) def test_dqi_valid_before_2025(): - reference_period = ReferencePeriod(start=DateTime("2023-01-01T00:00:00Z"), end=DateTime("2024-01-01T00:00:00Z")) - dqi = DataQualityIndicators(reference_period=reference_period, - technological_dqr=DataQualityRating(2)) # Other attributes are optional + reference_period = ReferencePeriod( + start=DateTime("2023-01-01T00:00:00Z"), end=DateTime("2024-01-01T00:00:00Z") + ) + dqi = DataQualityIndicators( + reference_period=reference_period, technological_dqr=DataQualityRating(2) + ) # Other attributes are optional assert dqi.technological_dqr == DataQualityRating(2) def test_dqi_valid_after_2025_all_attributes(): - reference_period = ReferencePeriod(start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z")) + reference_period = ReferencePeriod( + start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z") + ) dqi = DataQualityIndicators( - reference_period=reference_period, coverage_percent=80.0, technological_dqr=DataQualityRating(2), temporal_dqr=DataQualityRating(2), - geographical_dqr=DataQualityRating(1), completeness_dqr=DataQualityRating(2), reliability_dqr=DataQualityRating(3)) + reference_period=reference_period, + coverage_percent=80.0, + technological_dqr=DataQualityRating(2), + temporal_dqr=DataQualityRating(2), + geographical_dqr=DataQualityRating(1), + completeness_dqr=DataQualityRating(2), + reliability_dqr=DataQualityRating(3), + ) assert dqi.coverage_percent == 80.0 @@ -51,6 +78,12 @@ def test_dqi_missing_reference_period(): def test_dqi_invalid_dqr_type(): - reference_period = ReferencePeriod(start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z")) + reference_period = ReferencePeriod( + start=DateTime("2025-01-01T00:00:00Z"), end=DateTime("2026-01-01T00:00:00Z") + ) with pytest.raises(TypeError): - DataQualityIndicators(reference_period=reference_period, coverage_percent=50, technological_dqr=2.0) # DQR should be a DataQualityRating instance + DataQualityIndicators( + reference_period=reference_period, + coverage_percent=50, + technological_dqr=2.0, + ) # DQR should be a DataQualityRating instance diff --git a/tests/data_quality_indicators/test_data_quality_rating.py b/tests/data_quality_indicators/test_data_quality_rating.py index ac30f64..5f07a56 100644 --- a/tests/data_quality_indicators/test_data_quality_rating.py +++ b/tests/data_quality_indicators/test_data_quality_rating.py @@ -1,6 +1,8 @@ import pytest -from pathfinder_framework.data_quality_indicators.data_quality_rating import DataQualityRating +from pathfinder_framework.data_quality_indicators.data_quality_rating import ( + DataQualityRating, +) @pytest.mark.parametrize("rating", [1, 2, 3]) diff --git a/tests/product_footprint/test_company_id_list.py b/tests/product_footprint/test_company_id_list.py index 8ee107f..41479a5 100644 --- a/tests/product_footprint/test_company_id_list.py +++ b/tests/product_footprint/test_company_id_list.py @@ -6,46 +6,73 @@ def test_company_id_list_valid_company_ids(): - company_ids = [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp")] + company_ids = [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") + ] company_id_list = CompanyIdList(company_ids) assert len(company_id_list) == 1 assert isinstance(company_id_list[0], CompanyId) -@pytest.mark.parametrize("company_ids", [ - 123, 1.0, None, "string", {}, CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") -]) +@pytest.mark.parametrize( + "company_ids", + [ + 123, + 1.0, + None, + "string", + {}, + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + ], +) def test_company_id_list_invalid_company_ids(company_ids): with pytest.raises(ValueError, match="company_ids must be a list of CompanyId"): CompanyIdList(company_ids) -@pytest.mark.parametrize("company_ids", [ - ["string"], # list with a single invalid item - [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), "string"], # list with a mix of valid and invalid items - [1, 2, 3], # list with invalid items of a different type - [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), "string"], # list with multiple valid items and an invalid item -]) +@pytest.mark.parametrize( + "company_ids", + [ + ["string"], # list with a single invalid item + [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + "string", + ], # list with a mix of valid and invalid items + [1, 2, 3], # list with invalid items of a different type + [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + "string", + ], # list with multiple valid items and an invalid item + ], +) def test_company_id_list_invalid_company_ids_list(company_ids): with pytest.raises(ValueError, match="company_ids must be a list of CompanyId"): CompanyIdList(company_ids) def test_company_id_list_duplicate_company_ids(): - company_ids = [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp")] + company_ids = [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + ] with pytest.raises(DuplicateIdError, match="Duplicate company_ids are not allowed"): CompanyIdList(company_ids) def test_company_id_list_append_duplicate_company_id(): - company_ids = [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp")] + company_ids = [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") + ] company_id_list = CompanyIdList(company_ids) with pytest.raises(DuplicateIdError, match="Duplicate company_ids are not allowed"): company_id_list.append(company_ids[0]) def test_company_id_list_insert_duplicate_company_id(): - company_ids = [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp")] + company_ids = [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") + ] company_id_list = CompanyIdList(company_ids) with pytest.raises(DuplicateIdError, match="Duplicate company_ids are not allowed"): - company_id_list.insert(0, company_ids[0]) \ No newline at end of file + company_id_list.insert(0, company_ids[0]) diff --git a/tests/product_footprint/test_cpc.py b/tests/product_footprint/test_cpc.py index 543c265..91a844f 100644 --- a/tests/product_footprint/test_cpc.py +++ b/tests/product_footprint/test_cpc.py @@ -9,22 +9,25 @@ def cpc_code_lookup(): def test_cpc_class(): - cpc = CPC('0111', 'Wheat') - assert cpc.code == '0111' - assert cpc.title == 'Wheat' - assert cpc.section == '0' - assert cpc.division == '01' - assert cpc.group == '011' - assert cpc.class_ == '0111' - assert cpc.subclass == '0111' + cpc = CPC("0111", "Wheat") + assert cpc.code == "0111" + assert cpc.title == "Wheat" + assert cpc.section == "0" + assert cpc.division == "01" + assert cpc.group == "011" + assert cpc.class_ == "0111" + assert cpc.subclass == "0111" -@pytest.mark.parametrize("cpc_code, expected_title", [ - ("1202", "Natural gas, liquefied or in the gaseous state"), - ("1410", "Iron ores and concentrates, other than roasted iron pyrites"), - ("43310", "Ball or roller bearings"), - ("97120", "Dry-cleaning services (including fur product cleaning services)"), -]) +@pytest.mark.parametrize( + "cpc_code, expected_title", + [ + ("1202", "Natural gas, liquefied or in the gaseous state"), + ("1410", "Iron ores and concentrates, other than roasted iron pyrites"), + ("43310", "Ball or roller bearings"), + ("97120", "Dry-cleaning services (including fur product cleaning services)"), + ], +) def test_lookup_valid_cpc_code(cpc_code_lookup, cpc_code, expected_title): cpc = cpc_code_lookup.lookup(cpc_code) assert cpc.code == cpc_code @@ -32,42 +35,48 @@ def test_lookup_valid_cpc_code(cpc_code_lookup, cpc_code, expected_title): def test_lookup_cpc_code(cpc_code_lookup): - cpc = cpc_code_lookup.lookup('0') - assert cpc.code == '0' - assert cpc.title == 'Agriculture, forestry and fishery products' - assert cpc.section == '0' - assert cpc.division == '0' - assert cpc.group == '0' - assert cpc.class_ == '0' - assert cpc.subclass == '0' + cpc = cpc_code_lookup.lookup("0") + assert cpc.code == "0" + assert cpc.title == "Agriculture, forestry and fishery products" + assert cpc.section == "0" + assert cpc.division == "0" + assert cpc.group == "0" + assert cpc.class_ == "0" + assert cpc.subclass == "0" -@pytest.mark.parametrize("cpc_code", [ - "99999", # invalid code -]) +@pytest.mark.parametrize( + "cpc_code", + [ + "99999", # invalid code + ], +) def test_lookup_invalid_cpc_code(cpc_code_lookup, cpc_code): cpc = cpc_code_lookup.lookup(cpc_code) assert cpc is None def test_lookup_cpc_code_with_leading_zeros(cpc_code_lookup): - cpc = cpc_code_lookup.lookup('0112') - assert cpc.code == '0112' - assert cpc.title == 'Maize (corn)' - assert cpc.section == '0' - assert cpc.division == '01' - assert cpc.group == '011' - assert cpc.class_ == '0112' - assert cpc.subclass == '0112' + cpc = cpc_code_lookup.lookup("0112") + assert cpc.code == "0112" + assert cpc.title == "Maize (corn)" + assert cpc.section == "0" + assert cpc.division == "01" + assert cpc.group == "011" + assert cpc.class_ == "0112" + assert cpc.subclass == "0112" -@pytest.mark.parametrize("cpc_code", [ - "", - "abcde", - "123abc", - "123456", # code too long - "abcde", # non-numeric code -]) +@pytest.mark.parametrize( + "cpc_code", + [ + "", + "abcde", + "123abc", + "123456", # code too long + "abcde", # non-numeric code + ], +) def test_lookup_invalid_cpc_code_format(cpc_code_lookup, cpc_code): with pytest.raises(ValueError): cpc_code_lookup.lookup(cpc_code) diff --git a/tests/product_footprint/test_id.py b/tests/product_footprint/test_id.py index bf2b556..f93d4aa 100644 --- a/tests/product_footprint/test_id.py +++ b/tests/product_footprint/test_id.py @@ -35,4 +35,4 @@ def test_product_footprint_id_version(): def test_product_footprint_id_init_invalid_uuid(): with pytest.raises(ValueError): - ProductFootprintId('invalid-uuid-string') + ProductFootprintId("invalid-uuid-string") diff --git a/tests/product_footprint/test_product_footprint.py b/tests/product_footprint/test_product_footprint.py index 5c1da27..2986405 100644 --- a/tests/product_footprint/test_product_footprint.py +++ b/tests/product_footprint/test_product_footprint.py @@ -4,7 +4,10 @@ from pathfinder_framework.carbon_footprint.carbon_footprint import CarbonFootprint from pathfinder_framework.assurance.assurance import ( - Assurance, Coverage, Level, Boundary + Assurance, + Coverage, + Level, + Boundary, ) from pathfinder_framework.product_footprint.id import ProductFootprintId from pathfinder_framework.product_footprint.product_footprint import ProductFootprint @@ -13,17 +16,27 @@ from pathfinder_framework.product_footprint.cpc import CPCCodeLookup, CPC from pathfinder_framework.product_footprint.version import Version from pathfinder_framework.datetime import DateTime -from pathfinder_framework.carbon_footprint.characterization_factors import CharacterizationFactors -from pathfinder_framework.carbon_footprint.cross_sectoral_standard import CrossSectoralStandard +from pathfinder_framework.carbon_footprint.characterization_factors import ( + CharacterizationFactors, +) +from pathfinder_framework.carbon_footprint.cross_sectoral_standard import ( + CrossSectoralStandard, +) from pathfinder_framework.carbon_footprint.declared_unit import DeclaredUnit from pathfinder_framework.datetime import DateTime from pathfinder_framework.carbon_footprint.reference_period import ReferencePeriod from pathfinder_framework.carbon_footprint.geographical_scope import ( - CarbonFootprintGeographicalScope, GeographicalGranularity + CarbonFootprintGeographicalScope, + GeographicalGranularity, +) +from pathfinder_framework.data_quality_indicators.data_quality_indicators import ( + DataQualityIndicators, ) -from pathfinder_framework.data_quality_indicators.data_quality_indicators import DataQualityIndicators from pathfinder_framework.product_footprint.validity_period import ValidityPeriod -from pathfinder_framework.data_model_extension.data_model_extension import DataModelExtension +from pathfinder_framework.data_model_extension.data_model_extension import ( + DataModelExtension, +) + @pytest.fixture(scope="module") def company_ids() -> list[CompanyId]: @@ -38,7 +51,7 @@ def product_ids() -> list[ProductId]: @pytest.fixture(scope="module") def valid_cpc() -> CPC: cpc_code_lookup = CPCCodeLookup() - return cpc_code_lookup.lookup('0111') + return cpc_code_lookup.lookup("0111") @pytest.fixture(scope="module") @@ -63,11 +76,16 @@ def valid_carbon_footprint_data(): "exempted_emissions_percent": 1.0, "reference_period": ReferencePeriod(start=DateTime.now(), end=DateTime.now()), "packaging_emissions_included": True, - "geographical_scope": CarbonFootprintGeographicalScope(global_scope=True, geography_country_subdivision=None, - geography_country=None, - geography_region_or_subregion=None), + "geographical_scope": CarbonFootprintGeographicalScope( + global_scope=True, + geography_country_subdivision=None, + geography_country=None, + geography_region_or_subregion=None, + ), "primary_data_share": 50.0, - "dqi": DataQualityIndicators(reference_period=ReferencePeriod(start=DateTime.now(), end=DateTime.now())), + "dqi": DataQualityIndicators( + reference_period=ReferencePeriod(start=DateTime.now(), end=DateTime.now()) + ), "d_luc_ghg_emissions": 2, "land_management_ghg_emissions": 1.0, "other_biogenic_ghg_emissions": 1.5, @@ -86,7 +104,7 @@ def valid_carbon_footprint_data(): completed_at=DateTime.now(), standard_name="Example standard name", comments="Example comments", - ) + ), } @@ -97,14 +115,24 @@ def carbon_footprint(valid_carbon_footprint_data): @pytest.fixture def valid_product_footprint_data(valid_carbon_footprint_data): - company_ids = [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp")] - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] + company_ids = [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") + ] + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ] cpc_code_lookup = CPCCodeLookup() - valid_cpc = cpc_code_lookup.lookup('0111') + valid_cpc = cpc_code_lookup.lookup("0111") version = Version(1) validity_period = ValidityPeriod(DateTime.now(), DateTime.now()) - extensions = [DataModelExtension(spec_version="2.0.0", data_schema="https://example.com/schema", data={"key": "value"})] + extensions = [ + DataModelExtension( + spec_version="2.0.0", + data_schema="https://example.com/schema", + data={"key": "value"}, + ) + ] return { "id": ProductFootprintId(), @@ -122,7 +150,7 @@ def valid_product_footprint_data(valid_carbon_footprint_data): "product_name_company": "Product Name Company", "comment": "This is a comment", "extensions": extensions, - "pcf": CarbonFootprint(**valid_carbon_footprint_data) + "pcf": CarbonFootprint(**valid_carbon_footprint_data), } @@ -137,14 +165,20 @@ def test_product_footprint_initialization(valid_product_footprint_data): assert product_footprint.status_comment == "This is a comment" assert isinstance(product_footprint.validity_period, ValidityPeriod) assert product_footprint.company_name == "Company Name" - assert product_footprint.company_ids == [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp")] + assert product_footprint.company_ids == [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") + ] assert product_footprint.product_description == "Product Description" - assert product_footprint.product_ids == [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] - assert product_footprint.product_category_cpc == CPCCodeLookup().lookup('0111') + assert product_footprint.product_ids == [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ] + assert product_footprint.product_category_cpc == CPCCodeLookup().lookup("0111") assert product_footprint.product_name_company == "Product Name Company" assert product_footprint.comment == "This is a comment" assert isinstance(product_footprint.extensions, list) - assert all(isinstance(ext, DataModelExtension) for ext in product_footprint.extensions) + assert all( + isinstance(ext, DataModelExtension) for ext in product_footprint.extensions + ) assert isinstance(product_footprint.pcf, CarbonFootprint) @@ -154,7 +188,10 @@ def test_product_footprint_spec_version(valid_product_footprint_data): def test_product_footprint_invalid_spec_version(valid_product_footprint_data): - invalid_product_footprint_data = {**valid_product_footprint_data, "spec_version": "1.0.0"} + invalid_product_footprint_data = { + **valid_product_footprint_data, + "spec_version": "1.0.0", + } with pytest.raises(ValueError, match="Invalid spec version"): ProductFootprint(**invalid_product_footprint_data) @@ -194,51 +231,77 @@ def test_product_footprint_valid_updated(valid_product_footprint_data, updated): assert product_footprint.updated == updated -@pytest.mark.parametrize("updated", ["2022-01-01", datetime.now(), 1643723400, 1.0, None]) +@pytest.mark.parametrize( + "updated", ["2022-01-01", datetime.now(), 1643723400, 1.0, None] +) def test_product_footprint_invalid_updated(valid_product_footprint_data, updated): product_footprint_data = {**valid_product_footprint_data, "updated": updated} with pytest.raises(ValueError, match="updated must be an instance of DateTime"): ProductFootprint(**product_footprint_data) -@pytest.mark.parametrize("status", [ProductFootprintStatus.ACTIVE, ProductFootprintStatus.DEPRECATED]) +@pytest.mark.parametrize( + "status", [ProductFootprintStatus.ACTIVE, ProductFootprintStatus.DEPRECATED] +) def test_product_footprint_valid_status(valid_product_footprint_data, status): product_footprint_data = {**valid_product_footprint_data, "status": status} product_footprint = ProductFootprint(**product_footprint_data) assert product_footprint.status == status -@pytest.mark.parametrize("status", ["Active", "Deprecated",1, 1.0, datetime.now()]) +@pytest.mark.parametrize("status", ["Active", "Deprecated", 1, 1.0, datetime.now()]) def test_product_footprint_invalid_status(valid_product_footprint_data, status): product_footprint_data = {**valid_product_footprint_data, "status": status} - with pytest.raises(ValueError, match="status must be an instance of ProductFootprintStatus"): + with pytest.raises( + ValueError, match="status must be an instance of ProductFootprintStatus" + ): ProductFootprint(**product_footprint_data) @pytest.mark.parametrize("status_comment", ["This is a comment", "Another comment"]) -def test_product_footprint_valid_status_comment(valid_product_footprint_data, status_comment): - product_footprint_data = {**valid_product_footprint_data, "status_comment": status_comment} +def test_product_footprint_valid_status_comment( + valid_product_footprint_data, status_comment +): + product_footprint_data = { + **valid_product_footprint_data, + "status_comment": status_comment, + } product_footprint = ProductFootprint(**product_footprint_data) assert product_footprint.status_comment == status_comment @pytest.mark.parametrize("status_comment", [1, 1.0, datetime.now(), None]) -def test_product_footprint_invalid_status_comment(valid_product_footprint_data, status_comment): - product_footprint_data = {**valid_product_footprint_data, "status_comment": status_comment} +def test_product_footprint_invalid_status_comment( + valid_product_footprint_data, status_comment +): + product_footprint_data = { + **valid_product_footprint_data, + "status_comment": status_comment, + } with pytest.raises(ValueError, match="status_comment must be a string"): ProductFootprint(**product_footprint_data) def test_product_footprint_valid_validity_period(valid_product_footprint_data): - validity_period = ValidityPeriod(DateTime("2022-01-01T00:00:00Z"), DateTime("2025-12-31T23:59:59Z")) - product_footprint_data = {**valid_product_footprint_data, "validity_period": validity_period} + validity_period = ValidityPeriod( + DateTime("2022-01-01T00:00:00Z"), DateTime("2025-12-31T23:59:59Z") + ) + product_footprint_data = { + **valid_product_footprint_data, + "validity_period": validity_period, + } product_footprint = ProductFootprint(**product_footprint_data) assert product_footprint.validity_period == validity_period @pytest.mark.parametrize("company_name", [123, 1.0, None, [], {}, ""]) -def test_product_footprint_invalid_company_name(valid_product_footprint_data, company_name): - invalid_product_footprint_data = {**valid_product_footprint_data, "company_name": company_name} +def test_product_footprint_invalid_company_name( + valid_product_footprint_data, company_name +): + invalid_product_footprint_data = { + **valid_product_footprint_data, + "company_name": company_name, + } with pytest.raises(ValueError, match="company_name must be a non-empty string"): ProductFootprint(**invalid_product_footprint_data) @@ -249,9 +312,16 @@ def test_product_footprint_company_name(valid_product_footprint_data): @pytest.mark.parametrize("product_description", [123, 1.0, None, [], {}, ""]) -def test_product_footprint_invalid_product_description(valid_product_footprint_data, product_description): - invalid_product_footprint_data = {**valid_product_footprint_data, "product_description": product_description} - with pytest.raises(ValueError, match="product_description must be a non-empty string"): +def test_product_footprint_invalid_product_description( + valid_product_footprint_data, product_description +): + invalid_product_footprint_data = { + **valid_product_footprint_data, + "product_description": product_description, + } + with pytest.raises( + ValueError, match="product_description must be a non-empty string" + ): ProductFootprint(**invalid_product_footprint_data) @@ -261,9 +331,16 @@ def test_product_footprint_product_description(valid_product_footprint_data): @pytest.mark.parametrize("product_name_company", [123, 1.0, None, [], {}, ""]) -def test_product_footprint_invalid_product_name_company(valid_product_footprint_data, product_name_company): - invalid_product_footprint_data = {**valid_product_footprint_data, "product_name_company": product_name_company} - with pytest.raises(ValueError, match="product_name_company must be a non-empty string"): +def test_product_footprint_invalid_product_name_company( + valid_product_footprint_data, product_name_company +): + invalid_product_footprint_data = { + **valid_product_footprint_data, + "product_name_company": product_name_company, + } + with pytest.raises( + ValueError, match="product_name_company must be a non-empty string" + ): ProductFootprint(**invalid_product_footprint_data) @@ -271,91 +348,195 @@ def test_product_footprint_product_name_company(valid_product_footprint_data): product_footprint = ProductFootprint(**valid_product_footprint_data) assert product_footprint.product_name_company == "Product Name Company" -@pytest.mark.parametrize("company_ids", [ - [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp")], # list with a single item - [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp2")], # list with multiple items -]) + +@pytest.mark.parametrize( + "company_ids", + [ + [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") + ], # list with a single item + [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp2"), + ], # list with multiple items + ], +) def test_product_footprint_company_ids(valid_product_footprint_data, company_ids): - product_footprint_data = {**valid_product_footprint_data, "company_ids": company_ids} + product_footprint_data = { + **valid_product_footprint_data, + "company_ids": company_ids, + } product_footprint = ProductFootprint(**product_footprint_data) assert len(product_footprint.company_ids) == len(company_ids) for company_id in product_footprint.company_ids: assert isinstance(company_id, CompanyId) -@pytest.mark.parametrize("company_ids", [123, 1.0, None, "string", {}, CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp")]) -def test_product_footprint_invalid_company_ids(valid_product_footprint_data, company_ids): - invalid_product_footprint_data = {**valid_product_footprint_data, "company_ids": company_ids} +@pytest.mark.parametrize( + "company_ids", + [ + 123, + 1.0, + None, + "string", + {}, + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + ], +) +def test_product_footprint_invalid_company_ids( + valid_product_footprint_data, company_ids +): + invalid_product_footprint_data = { + **valid_product_footprint_data, + "company_ids": company_ids, + } with pytest.raises(ValueError, match="company_ids must be a list of CompanyId"): ProductFootprint(**invalid_product_footprint_data) -@pytest.mark.parametrize("product_ids", [ - [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")], # list with a single item - [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product2")], # list with multiple items -]) +@pytest.mark.parametrize( + "product_ids", + [ + [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ], # list with a single item + [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product2"), + ], # list with multiple items + ], +) def test_product_footprint_product_ids(valid_product_footprint_data, product_ids): - product_footprint_data = {**valid_product_footprint_data, "product_ids": product_ids} + product_footprint_data = { + **valid_product_footprint_data, + "product_ids": product_ids, + } product_footprint = ProductFootprint(**product_footprint_data) assert len(product_footprint.product_ids) == len(product_ids) for product_id in product_footprint.product_ids: assert isinstance(product_id, ProductId) -@pytest.mark.parametrize("product_ids", [123, 1.0, None, "string", {}, ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")]) -def test_product_footprint_invalid_product_ids(valid_product_footprint_data, product_ids): - invalid_product_footprint_data = {**valid_product_footprint_data, "product_ids": product_ids} +@pytest.mark.parametrize( + "product_ids", + [ + 123, + 1.0, + None, + "string", + {}, + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + ], +) +def test_product_footprint_invalid_product_ids( + valid_product_footprint_data, product_ids +): + invalid_product_footprint_data = { + **valid_product_footprint_data, + "product_ids": product_ids, + } with pytest.raises(ValueError, match="product_ids must be a list of ProductId"): ProductFootprint(**invalid_product_footprint_data) -@pytest.mark.parametrize("company_ids", [ - ["string"], # list with a single invalid item - [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), "string"], # list with a mix of valid and invalid items - [1, 2, 3], # list with invalid items of a different type - [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), "string"], # list with multiple valid items and an invalid item -]) -def test_product_footprint_invalid_company_ids_list(valid_product_footprint_data, company_ids): - invalid_product_footprint_data = {**valid_product_footprint_data, "company_ids": company_ids} +@pytest.mark.parametrize( + "company_ids", + [ + ["string"], # list with a single invalid item + [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + "string", + ], # list with a mix of valid and invalid items + [1, 2, 3], # list with invalid items of a different type + [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + "string", + ], # list with multiple valid items and an invalid item + ], +) +def test_product_footprint_invalid_company_ids_list( + valid_product_footprint_data, company_ids +): + invalid_product_footprint_data = { + **valid_product_footprint_data, + "company_ids": company_ids, + } with pytest.raises(ValueError, match="company_ids must be a list of CompanyId"): ProductFootprint(**invalid_product_footprint_data) -@pytest.mark.parametrize("product_ids", [ - ["string"], # list with a single invalid item - [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), "string"], # list with a mix of valid and invalid items - [1, 2, 3], # list with invalid items of a different type - [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), "string"], # list with multiple valid items and an invalid item -]) -def test_product_footprint_invalid_product_ids_list(valid_product_footprint_data, product_ids): - invalid_product_footprint_data = {**valid_product_footprint_data, "product_ids": product_ids} +@pytest.mark.parametrize( + "product_ids", + [ + ["string"], # list with a single invalid item + [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + "string", + ], # list with a mix of valid and invalid items + [1, 2, 3], # list with invalid items of a different type + [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + "string", + ], # list with multiple valid items and an invalid item + ], +) +def test_product_footprint_invalid_product_ids_list( + valid_product_footprint_data, product_ids +): + invalid_product_footprint_data = { + **valid_product_footprint_data, + "product_ids": product_ids, + } with pytest.raises(ValueError, match="product_ids must be a list of ProductId"): ProductFootprint(**invalid_product_footprint_data) @pytest.mark.xfail(reason="Functionality not implemented yet") def test_product_footprint_duplicate_company_ids(valid_product_footprint_data): - company_ids = [CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp")] - product_footprint_data = {**valid_product_footprint_data, "company_ids": company_ids} + company_ids = [ + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp"), + ] + product_footprint_data = { + **valid_product_footprint_data, + "company_ids": company_ids, + } with pytest.raises(ValueError, match="Duplicate company_ids are not allowed"): ProductFootprint(**product_footprint_data) + @pytest.mark.xfail(reason="Functionality not implemented yet") def test_product_footprint_duplicate_product_ids(valid_product_footprint_data): - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] - product_footprint_data = {**valid_product_footprint_data, "product_ids": product_ids} + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + ] + product_footprint_data = { + **valid_product_footprint_data, + "product_ids": product_ids, + } with pytest.raises(ValueError, match="Duplicate product_ids are not allowed"): ProductFootprint(**product_footprint_data) + def test_product_footprint_product_category_cpc(valid_product_footprint_data): product_footprint = ProductFootprint(**valid_product_footprint_data) assert isinstance(product_footprint.product_category_cpc, CPC) @pytest.mark.parametrize("product_category_cpc", [123, 1.0, None, "string", {}, []]) -def test_product_footprint_invalid_product_category_cpc(valid_product_footprint_data, product_category_cpc): - invalid_product_footprint_data = {**valid_product_footprint_data, "product_category_cpc": product_category_cpc} - with pytest.raises(ValueError, match="product_category_cpc must be an instance of CPC"): +def test_product_footprint_invalid_product_category_cpc( + valid_product_footprint_data, product_category_cpc +): + invalid_product_footprint_data = { + **valid_product_footprint_data, + "product_category_cpc": product_category_cpc, + } + with pytest.raises( + ValueError, match="product_category_cpc must be an instance of CPC" + ): ProductFootprint(**invalid_product_footprint_data) @@ -366,7 +547,10 @@ def test_product_footprint_comment(valid_product_footprint_data): @pytest.mark.parametrize("comment", [123, 1.0, None, {}, []]) def test_product_footprint_invalid_comment(valid_product_footprint_data, comment): - invalid_product_footprint_data = {**valid_product_footprint_data, "comment": comment} + invalid_product_footprint_data = { + **valid_product_footprint_data, + "comment": comment, + } with pytest.raises(ValueError, match="comment must be a string"): ProductFootprint(**invalid_product_footprint_data) @@ -374,13 +558,20 @@ def test_product_footprint_invalid_comment(valid_product_footprint_data, comment def test_product_footprint_extensions(valid_product_footprint_data): product_footprint = ProductFootprint(**valid_product_footprint_data) assert isinstance(product_footprint.extensions, list) - assert all(isinstance(ext, DataModelExtension) for ext in product_footprint.extensions) + assert all( + isinstance(ext, DataModelExtension) for ext in product_footprint.extensions + ) @pytest.mark.parametrize("extensions", [123, 1.0, None, "string", {}]) def test_product_footprint_invalid_extensions(valid_product_footprint_data, extensions): - invalid_product_footprint_data = {**valid_product_footprint_data, "extensions": extensions} - with pytest.raises(ValueError, match="extensions must be a list of DataModelExtension objects"): + invalid_product_footprint_data = { + **valid_product_footprint_data, + "extensions": extensions, + } + with pytest.raises( + ValueError, match="extensions must be a list of DataModelExtension objects" + ): ProductFootprint(**invalid_product_footprint_data) @@ -393,4 +584,4 @@ def test_product_footprint_pcf(valid_product_footprint_data): def test_product_footprint_invalid_pcf(valid_product_footprint_data, pcf): invalid_product_footprint_data = {**valid_product_footprint_data, "pcf": pcf} with pytest.raises(ValueError, match="pcf must be an instance of CarbonFootprint"): - ProductFootprint(**invalid_product_footprint_data) \ No newline at end of file + ProductFootprint(**invalid_product_footprint_data) diff --git a/tests/product_footprint/test_product_id_list.py b/tests/product_footprint/test_product_id_list.py index 1185dd9..241b052 100644 --- a/tests/product_footprint/test_product_id_list.py +++ b/tests/product_footprint/test_product_id_list.py @@ -5,83 +5,125 @@ from pathfinder_framework.product_footprint.product_id_list import ProductIdList - def test_product_id_list_valid_product_ids(): - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ] product_id_list = ProductIdList(product_ids) assert len(product_id_list) == 1 assert isinstance(product_id_list.product_ids[0], ProductId) -@pytest.mark.parametrize("product_ids", [123, 1.0, None, "string", {}, ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")]) +@pytest.mark.parametrize( + "product_ids", + [ + 123, + 1.0, + None, + "string", + {}, + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + ], +) def test_product_id_list_invalid_product_ids(product_ids): with pytest.raises(ValueError, match="product_ids must be a list of ProductId"): ProductIdList(product_ids) -@pytest.mark.parametrize("product_ids", [ - ["string"], # list with a single invalid item - [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), "string"], # list with a mix of valid and invalid items - [1, 2, 3], # list with invalid items of a different type - [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), "string"], # list with multiple valid items and an invalid item -]) +@pytest.mark.parametrize( + "product_ids", + [ + ["string"], # list with a single invalid item + [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + "string", + ], # list with a mix of valid and invalid items + [1, 2, 3], # list with invalid items of a different type + [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + "string", + ], # list with multiple valid items and an invalid item + ], +) def test_product_id_list_invalid_product_ids_list(product_ids): with pytest.raises(ValueError, match="product_ids must be a list of ProductId"): ProductIdList(product_ids) def test_product_id_list_duplicate_product_ids(): - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product"), + ] with pytest.raises(DuplicateIdError, match="Duplicate product_ids are not allowed"): ProductIdList(product_ids) def test_product_id_list_append_valid_product_id(): - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ] product_id_list = ProductIdList(product_ids) - new_product_id = ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product2") + new_product_id = ProductId( + "urn:pathfinder:product:customcode:buyer-assigned:acme-product2" + ) product_id_list.append(new_product_id) assert len(product_id_list) == 2 assert product_id_list.product_ids[1] == new_product_id def test_product_id_list_append_invalid_product_id(): - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ] product_id_list = ProductIdList(product_ids) with pytest.raises(ValueError, match="product_id must be an instance of ProductId"): product_id_list.append("string") def test_product_id_list_append_duplicate_product_id(): - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ] product_id_list = ProductIdList(product_ids) with pytest.raises(DuplicateIdError, match="Duplicate product_ids are not allowed"): product_id_list.append(product_ids[0]) def test_product_id_list_insert_duplicate_product_id(): - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ] product_id_list = ProductIdList(product_ids) with pytest.raises(DuplicateIdError, match="Duplicate product_ids are not allowed"): product_id_list.insert(0, product_ids[0]) def test_product_id_list_insert_invalid_product_id(): - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ] product_id_list = ProductIdList(product_ids) with pytest.raises(ValueError, match="product_id must be an instance of ProductId"): product_id_list.insert(0, "string") def test_product_id_list_remove_valid_product_id(): - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ] product_id_list = ProductIdList(product_ids) product_id_list.remove(product_ids[0]) assert len(product_id_list) == 0 def test_product_id_list_remove_invalid_product_id(): - product_ids = [ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product")] + product_ids = [ + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product") + ] product_id_list = ProductIdList(product_ids) with pytest.raises(ValueError, match="product_id is not in the list"): - product_id_list.remove(ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product2")) \ No newline at end of file + product_id_list.remove( + ProductId("urn:pathfinder:product:customcode:buyer-assigned:acme-product2") + ) diff --git a/tests/product_footprint/test_validity_period.py b/tests/product_footprint/test_validity_period.py index 0308ac0..9dd2c6a 100644 --- a/tests/product_footprint/test_validity_period.py +++ b/tests/product_footprint/test_validity_period.py @@ -54,4 +54,4 @@ def test_validity_period_init_raises_value_error_for_start_date_not_before_end_d start = DateTime("2025-01-01T00:00:00Z") end = DateTime("2022-12-31T23:59:59Z") with pytest.raises(ValueError, match="Start date must be before end date"): - ValidityPeriod(start, end) \ No newline at end of file + ValidityPeriod(start, end) diff --git a/tests/test_datetime.py b/tests/test_datetime.py index 4856f11..05c837a 100644 --- a/tests/test_datetime.py +++ b/tests/test_datetime.py @@ -16,12 +16,16 @@ def test_valid_iso_8601_string_with_offset(): def test_invalid_iso_8601_string_with_offset(): with pytest.raises(ValueError): - DateTime("2020-03-01T00:00:00+01:00") # This is a valid ISO 8601 string, but not in the correct format + DateTime( + "2020-03-01T00:00:00+01:00" + ) # This is a valid ISO 8601 string, but not in the correct format def test_invalid_iso_8601_string_without_tzinfo(): with pytest.raises(ValueError): - DateTime("2020-03-01T00:00:00") # This is a valid ISO 8601 string, but not in the correct format + DateTime( + "2020-03-01T00:00:00" + ) # This is a valid ISO 8601 string, but not in the correct format def test_invalid_iso_8601_string_different_timezone(): @@ -53,10 +57,14 @@ def test_str(): def test_now(): dt = DateTime.now() - assert dt.value.endswith('Z') + assert dt.value.endswith("Z") # Check that the value is within the last minute (to account for possible delays) - assert datetime.fromisoformat(dt.value.replace('Z', '+00:00')) > datetime.now(timezone.utc) - timedelta(minutes=1) - assert datetime.fromisoformat(dt.value.replace('Z', '+00:00')) < datetime.now(timezone.utc) + timedelta(minutes=1) + assert datetime.fromisoformat(dt.value.replace("Z", "+00:00")) > datetime.now( + timezone.utc + ) - timedelta(minutes=1) + assert datetime.fromisoformat(dt.value.replace("Z", "+00:00")) < datetime.now( + timezone.utc + ) + timedelta(minutes=1) def test_now_multiple_calls(): @@ -69,13 +77,15 @@ def test_now_multiple_calls(): def test_now_format(): dt = DateTime.now() # Check that the value is in the correct format - datetime.fromisoformat(dt.value.replace('Z', '+00:00')) + datetime.fromisoformat(dt.value.replace("Z", "+00:00")) def test_now_timezone(): dt = DateTime.now() # Check that the value has the correct timezone - assert datetime.fromisoformat(dt.value.replace('Z', '+00:00')).tzinfo == timezone.utc + assert ( + datetime.fromisoformat(dt.value.replace("Z", "+00:00")).tzinfo == timezone.utc + ) def test_year(): diff --git a/tests/test_urn.py b/tests/test_urn.py index b60a159..0362dab 100644 --- a/tests/test_urn.py +++ b/tests/test_urn.py @@ -32,8 +32,8 @@ def test_uuid_urn(): "urn:pathfinder:product:customcode:buyer-assigned:1234", "urn:pathfinder:product:customcode:vendor-assigned:8765", "urn:pathfinder:product:id:cas:64-17-5", - "urn:pathfinder:product:id:iupac-inchi:1S%2FC9H8O4%2Fc1-6%2810%2913-8-5-3-2-4-7%288%299%2811%2912%2Fh2-5H%2C1H3%2C%28H%2C11%2C12%29" - ] + "urn:pathfinder:product:id:iupac-inchi:1S%2FC9H8O4%2Fc1-6%2810%2913-8-5-3-2-4-7%288%299%2811%2912%2Fh2-5H%2C1H3%2C%28H%2C11%2C12%29", + ], ) def test_valid_pathfinder_urns(urn_string): urn = URN(value=urn_string) @@ -43,7 +43,7 @@ def test_valid_pathfinder_urns(urn_string): def test_valid_company_ids(): valid_ids = [ "urn:pathfinder:company:customcode:buyer-assigned:acme-corp", - "urn:pathfinder:company:customcode:vendor-assigned:12345" + "urn:pathfinder:company:customcode:vendor-assigned:12345", ] for cid in valid_ids: CompanyId(value=cid) @@ -53,12 +53,13 @@ def test_invalid_company_ids(): invalid_ids = [ "urn:pathfinder:company:customcode:buyer-assigned:bad code", "urn:pathfinder:company:customcode:vendor-assigned:", - "not-a-company-id" + "not-a-company-id", ] for cid in invalid_ids: with pytest.raises(ValueError): CompanyId(value=cid) + @pytest.mark.parametrize( "product_id", [ @@ -67,8 +68,8 @@ def test_invalid_company_ids(): "urn:pathfinder:product:id:cas:64-17-5", "urn:pathfinder:product:id:cas:1067-08-9", "urn:pathfinder:product:id:cas:2306877-20-1", - "urn:pathfinder:product:id:iupac-inchi:1S/C9H8O4/c1-6(10)13-8-5-3-2-4-7(8)9(11)12/h2-5H,1H3,(H,11,12)" - ] + "urn:pathfinder:product:id:iupac-inchi:1S/C9H8O4/c1-6(10)13-8-5-3-2-4-7(8)9(11)12/h2-5H,1H3,(H,11,12)", + ], ) def test_valid_product_ids(product_id): pid = ProductId(value=product_id) @@ -82,21 +83,30 @@ def test_valid_product_ids(product_id): "urn:pathfinder:product:customcode:vendor-assigned:", "urn:pathfinder:product:id:cas:17-5", "urn:pathfinder:product:id:cas:1345678-08-9", - ] + ], ) def test_invalid_product_ids(product_id): with pytest.raises(ValueError): ProductId(value=product_id) + def test_company_id_hash(): company_id = CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") - assert hash(company_id) == hash("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") + assert hash(company_id) == hash( + "urn:pathfinder:company:customcode:buyer-assigned:acme-corp" + ) def test_company_id_hash_multiple(): - company_id1 = CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") - company_id2 = CompanyId("urn:pathfinder:company:customcode:buyer-assigned:acme-corp") - company_id3 = CompanyId("urn:pathfinder:company:customcode:buyer-assigned:other-corp") + company_id1 = CompanyId( + "urn:pathfinder:company:customcode:buyer-assigned:acme-corp" + ) + company_id2 = CompanyId( + "urn:pathfinder:company:customcode:buyer-assigned:acme-corp" + ) + company_id3 = CompanyId( + "urn:pathfinder:company:customcode:buyer-assigned:other-corp" + ) assert hash(company_id1) == hash(company_id2) - assert hash(company_id1) != hash(company_id3) \ No newline at end of file + assert hash(company_id1) != hash(company_id3)