hestia-earth-models 0.59.4__py3-none-any.whl → 0.59.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of hestia-earth-models might be problematic. Click here for more details.

Files changed (55) hide show
  1. hestia_earth/models/cycle/animal/milkYield.py +86 -0
  2. hestia_earth/models/cycle/endDate.py +50 -0
  3. hestia_earth/models/cycle/inorganicFertiliser.py +3 -2
  4. hestia_earth/models/cycle/liveAnimal.py +3 -0
  5. hestia_earth/models/cycle/milkYield.py +8 -3
  6. hestia_earth/models/cycle/pre_checks/__init__.py +1 -2
  7. hestia_earth/models/cycle/startDate.py +42 -0
  8. hestia_earth/models/cycle/utils.py +1 -1
  9. hestia_earth/models/faostat2018/liveweightPerHead.py +77 -41
  10. hestia_earth/models/faostat2018/product/price.py +30 -55
  11. hestia_earth/models/faostat2018/utils.py +10 -2
  12. hestia_earth/models/geospatialDatabase/potentialEvapotranspirationLongTermAnnualMean.py +2 -2
  13. hestia_earth/models/geospatialDatabase/potentialEvapotranspirationMonthly.py +9 -8
  14. hestia_earth/models/geospatialDatabase/precipitationMonthly.py +10 -8
  15. hestia_earth/models/geospatialDatabase/temperatureAnnual.py +2 -5
  16. hestia_earth/models/geospatialDatabase/temperatureLongTermAnnualMean.py +2 -3
  17. hestia_earth/models/geospatialDatabase/temperatureMonthly.py +8 -8
  18. hestia_earth/models/geospatialDatabase/utils.py +6 -1
  19. hestia_earth/models/haversineFormula/transport/distance.py +6 -3
  20. hestia_earth/models/ipcc2006/n2OToAirInorganicFertiliserIndirect.py +1 -1
  21. hestia_earth/models/ipcc2019/organicCarbonPerHa.py +89 -114
  22. hestia_earth/models/ipcc2019/pastureGrass.py +2 -1
  23. hestia_earth/models/linkedImpactAssessment/__init__.py +78 -43
  24. hestia_earth/models/mocking/search-results.json +244 -271
  25. hestia_earth/models/schmidt2007/h2SToAirWasteTreatment.py +58 -0
  26. hestia_earth/models/schmidt2007/n2OToAirWasteTreatmentDirect.py +58 -0
  27. hestia_earth/models/schmidt2007/nh3ToAirWasteTreatment.py +58 -0
  28. hestia_earth/models/site/management.py +107 -12
  29. hestia_earth/models/site/soilMeasurement.py +9 -9
  30. hestia_earth/models/utils/__init__.py +4 -1
  31. hestia_earth/models/utils/animalProduct.py +6 -4
  32. hestia_earth/models/utils/blank_node.py +6 -5
  33. hestia_earth/models/utils/product.py +9 -1
  34. hestia_earth/models/utils/term.py +0 -23
  35. hestia_earth/models/version.py +1 -1
  36. {hestia_earth_models-0.59.4.dist-info → hestia_earth_models-0.59.6.dist-info}/METADATA +1 -1
  37. {hestia_earth_models-0.59.4.dist-info → hestia_earth_models-0.59.6.dist-info}/RECORD +53 -43
  38. tests/models/cycle/animal/test_milkYield.py +43 -0
  39. tests/models/cycle/test_endDate.py +24 -0
  40. tests/models/cycle/test_startDate.py +22 -0
  41. tests/models/faostat2018/product/test_price.py +25 -45
  42. tests/models/faostat2018/test_liveweightPerHead.py +106 -42
  43. tests/models/ipcc2019/test_organicCarbonPerHa.py +12 -18
  44. tests/models/schmidt2007/test_h2SToAirWasteTreatment.py +45 -0
  45. tests/models/schmidt2007/test_n2OToAirWasteTreatmentDirect.py +45 -0
  46. tests/models/schmidt2007/test_nh3ToAirWasteTreatment.py +45 -0
  47. tests/models/site/test_management.py +24 -3
  48. tests/models/site/test_soilMeasurement.py +40 -21
  49. tests/models/utils/test_blank_node.py +71 -3
  50. tests/models/utils/test_term.py +1 -8
  51. hestia_earth/models/cycle/pre_checks/startDate.py +0 -52
  52. tests/models/cycle/pre_checks/test_startDate.py +0 -44
  53. {hestia_earth_models-0.59.4.dist-info → hestia_earth_models-0.59.6.dist-info}/LICENSE +0 -0
  54. {hestia_earth_models-0.59.4.dist-info → hestia_earth_models-0.59.6.dist-info}/WHEEL +0 -0
  55. {hestia_earth_models-0.59.4.dist-info → hestia_earth_models-0.59.6.dist-info}/top_level.txt +0 -0
@@ -1,61 +1,125 @@
1
1
  from unittest.mock import patch
2
2
  import json
3
3
 
4
- from hestia_earth.schema import TermTermType
5
4
  from tests.utils import fixtures_path, fake_new_property
6
5
 
7
- from hestia_earth.models.faostat2018.liveweightPerHead import MODEL, TERM_ID, _should_run, run
6
+ from hestia_earth.models.faostat2018.liveweightPerHead import MODEL, TERM_ID, run
8
7
 
9
8
  class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
10
9
  fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
11
- FAO_TERM = {
12
- '@id': 'meatChickenReadyToCookWeight',
13
- '@type': 'Term',
14
- 'units': 'kg ready-to-cook weight',
15
- 'defaultProperties': [{
16
- 'term': {'@id': 'processingConversionLiveweightToColdCarcassWeight', 'units': '%'},
17
- 'value': 72.30401869158878
18
- }, {
19
- 'term': {'@id': 'processingConversionColdCarcassWeightToReadyToCookWeight', 'units': '%'},
20
- 'value': 72.45065789473684
21
- }]
22
- }
23
-
24
-
25
- def test_should_run():
26
- cycle = {}
27
-
28
- # no animal products => no run
29
- should_run, *args = _should_run(cycle)
30
- assert not should_run
31
-
32
- # with animal products => no run
33
- cycle['products'] = [
34
- {
35
- 'term': {
36
- 'termType': TermTermType.ANIMALPRODUCT.value,
37
- 'units': 'kg liveweight'
10
+
11
+
12
+ @patch(f"{class_path}._new_property", side_effect=fake_new_property)
13
+ def test_run_animalProduct(*args):
14
+ with open(f"{fixtures_folder}/animalProduct/cycle.jsonld", encoding='utf-8') as f:
15
+ cycle = json.load(f)
16
+
17
+ with open(f"{fixtures_folder}/animalProduct/result.jsonld", encoding='utf-8') as f:
18
+ expected = json.load(f)
19
+
20
+ value = run(cycle)
21
+ assert value == expected
22
+
23
+
24
+ @patch(f"{class_path}._new_property", side_effect=fake_new_property)
25
+ @patch(f"{class_path}.download_hestia")
26
+ def test_run_liveAnimal_chicken(mock_download_hestia, *args):
27
+ with open(f"{fixtures_folder}/liveAnimal/chicken/cycle.jsonld", encoding='utf-8') as f:
28
+ cycle = json.load(f)
29
+
30
+ with open(f"{fixtures_folder}/liveAnimal/chicken/result.jsonld", encoding='utf-8') as f:
31
+ expected = json.load(f)
32
+
33
+ mock_download_hestia.return_value = {
34
+ "@id": "meatChickenReadyToCookWeight",
35
+ "@type": "Term",
36
+ "units": "kg ready-to-cook weight",
37
+ "defaultProperties": [
38
+ {
39
+ "term": {
40
+ "@type": "Term",
41
+ "name": "Processing conversion, liveweight to cold carcass weight",
42
+ "termType": "property",
43
+ "@id": "processingConversionLiveweightToColdCarcassWeight",
44
+ "units": "%"
45
+ },
46
+ "value": 72.30401869158878,
47
+ "@type": "Property"
48
+ },
49
+ {
50
+ "term": {
51
+ "@type": "Term",
52
+ "name": "Processing conversion, cold carcass weight to ready-to-cook weight",
53
+ "termType": "property",
54
+ "@id": "processingConversionColdCarcassWeightToReadyToCookWeight",
55
+ "units": "%"
56
+ },
57
+ "value": 72.45065789473684,
58
+ "@type": "Property"
38
59
  }
39
- }
40
- ]
41
- should_run, *args = _should_run(cycle)
42
- assert not should_run
60
+ ]
61
+ }
62
+ value = run(cycle)
63
+ assert value == expected
64
+
65
+
66
+ @patch(f"{class_path}._new_property", side_effect=fake_new_property)
67
+ @patch(f"{class_path}.download_hestia")
68
+ def test_run_liveAnimal_pig(mock_download_hestia, *args):
69
+ with open(f"{fixtures_folder}/liveAnimal/pig/cycle.jsonld", encoding='utf-8') as f:
70
+ cycle = json.load(f)
43
71
 
44
- # with an endDate and country => run
45
- cycle['endDate'] = '2020'
46
- cycle['site'] = {'country': {'@id': 'GADM-GBR'}}
47
- should_run, *args = _should_run(cycle)
48
- assert should_run is True
72
+ with open(f"{fixtures_folder}/liveAnimal/pig/result.jsonld", encoding='utf-8') as f:
73
+ expected = json.load(f)
74
+
75
+ mock_download_hestia.return_value = {
76
+ "@id": "meatPigColdDressedCarcassWeight",
77
+ "@type": "Term",
78
+ "units": "kg cold dressed carcass weight",
79
+ "defaultProperties": [
80
+ {
81
+ "term": {
82
+ "@type": "Term",
83
+ "name": "Processing conversion, liveweight to cold carcass weight",
84
+ "termType": "property",
85
+ "@id": "processingConversionLiveweightToColdCarcassWeight",
86
+ "units": "%"
87
+ },
88
+ "value": 75.22666597366735,
89
+ "@type": "Property"
90
+ }
91
+ ]
92
+ }
93
+ value = run(cycle)
94
+ assert value == expected
49
95
 
50
96
 
51
- @patch(f"hestia_earth.models.{MODEL}.utils.download_hestia", return_value=FAO_TERM)
52
97
  @patch(f"{class_path}._new_property", side_effect=fake_new_property)
53
- def test_run(*args):
54
- with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
98
+ @patch(f"{class_path}.download_hestia")
99
+ def test_run_liveAnimal_sheepLamb(mock_download_hestia, *args):
100
+ with open(f"{fixtures_folder}/liveAnimal/sheepLamb/cycle.jsonld", encoding='utf-8') as f:
55
101
  cycle = json.load(f)
56
102
 
57
- with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
103
+ with open(f"{fixtures_folder}/liveAnimal/sheepLamb/result.jsonld", encoding='utf-8') as f:
58
104
  expected = json.load(f)
59
105
 
106
+ mock_download_hestia.return_value = {
107
+ "@id": "meatSheepColdDressedCarcassWeight",
108
+ "@type": "Term",
109
+ "units": "kg cold dressed carcass weight",
110
+ "defaultProperties": [
111
+ {
112
+ "term": {
113
+ "@type": "Term",
114
+ "name": "Processing conversion, liveweight to cold carcass weight",
115
+ "termType": "property",
116
+ "@id": "processingConversionLiveweightToColdCarcassWeight",
117
+ "units": "%"
118
+ },
119
+ "value": 47.301833667687326,
120
+ "@type": "Property"
121
+ }
122
+ ]
123
+ }
60
124
  value = run(cycle)
61
125
  assert value == expected
@@ -67,11 +67,6 @@ IRRIGATED_TERM_IDS = [
67
67
  "irrigatedSurfaceIrrigationDrainageRegimeUnspecified"
68
68
  ]
69
69
 
70
- LONG_FALLOW_LAND_COVER_TERM_IDS = [
71
- "longFallow",
72
- "longBareFallow"
73
- ]
74
-
75
70
  RESIDUE_REMOVED_OR_BURNT_TERM_IDS = [
76
71
  "residueBurnt",
77
72
  "residueRemoved"
@@ -111,6 +106,7 @@ def find_term_property_side_effect(term: dict, property: str, *_):
111
106
  # subfolder, load_cycles
112
107
  RUN_SUBFOLDERS = [
113
108
  ("tier-1-and-2/cropland", True),
109
+ ("tier-1-and-2/with-zero-carbon-input", True), # Closes issue 777
114
110
  ("tier-2/with-generalised-monthly-measurements", True), # Closes issue 600
115
111
  ("tier-2/with-incomplete-climate-data", True), # Closes issue 599
116
112
  ("tier-2/with-initial-soc", True),
@@ -128,7 +124,9 @@ RUN_SUBFOLDERS = [
128
124
  ("tier-1/cropland-without-measured-soc", False),
129
125
  ("tier-1/permanent-pasture", False),
130
126
  ("tier-1/should-not-run", False),
131
- ("tier-1/without-management-with-measured-soc", False)
127
+ ("tier-1/without-management-with-measured-soc", False),
128
+ ("tier-1/land-use-change", False), # Closes issue 755
129
+ ("tier-1/run-with-site-type", False) # Closes issue 755
132
130
  ]
133
131
 
134
132
 
@@ -141,7 +139,6 @@ RUN_SUBFOLDERS = [
141
139
  @patch(f"{class_path}.get_cover_crop_property_terms", return_value=COVER_CROP_PROPERTY_TERM_IDS)
142
140
  @patch(f"{class_path}.get_crop_residue_incorporated_or_left_on_field_terms", return_value=CROP_RESIDUE_INCORP_TERM_IDS)
143
141
  @patch(f"{class_path}.get_irrigated_terms", return_value=IRRIGATED_TERM_IDS)
144
- @patch(f"{class_path}.get_long_fallow_land_cover_terms", return_value=LONG_FALLOW_LAND_COVER_TERM_IDS)
145
142
  @patch(f"{class_path}.get_residue_removed_or_burnt_terms", return_value=RESIDUE_REMOVED_OR_BURNT_TERM_IDS)
146
143
  @patch(f"{class_path}.get_upland_rice_land_cover_terms", return_value=UPLAND_RICE_LAND_COVER_TERM_IDS)
147
144
  @patch(f"{class_path}.get_upland_rice_crop_terms", return_value=UPLAND_RICE_CROP_TERM_IDS)
@@ -153,7 +150,6 @@ def test_run(
153
150
  _mock_get_upland_rice_crop_terms,
154
151
  _mock_get_upland_rice_land_cover_terms,
155
152
  _mock_get_residue_removed_or_burnt_terms,
156
- _mock_get_long_fallow_land_cover_terms,
157
153
  _mock_get_irrigated_terms,
158
154
  _mock_get_crop_residue_incorporated_or_left_on_field_terms,
159
155
  _mock_get_cover_crop_property_terms,
@@ -184,7 +180,6 @@ def test_run(
184
180
  @patch(f"{class_path}.get_cover_crop_property_terms", return_value=COVER_CROP_PROPERTY_TERM_IDS)
185
181
  @patch(f"{class_path}.get_crop_residue_incorporated_or_left_on_field_terms", return_value=CROP_RESIDUE_INCORP_TERM_IDS)
186
182
  @patch(f"{class_path}.get_irrigated_terms", return_value=IRRIGATED_TERM_IDS)
187
- @patch(f"{class_path}.get_long_fallow_land_cover_terms", return_value=LONG_FALLOW_LAND_COVER_TERM_IDS)
188
183
  @patch(f"{class_path}.get_residue_removed_or_burnt_terms", return_value=RESIDUE_REMOVED_OR_BURNT_TERM_IDS)
189
184
  @patch(f"{class_path}.get_upland_rice_land_cover_terms", return_value=UPLAND_RICE_LAND_COVER_TERM_IDS)
190
185
  @patch(f"{class_path}.get_upland_rice_crop_terms", return_value=UPLAND_RICE_CROP_TERM_IDS)
@@ -233,6 +228,13 @@ def test_calc_water_factor():
233
228
  assert _calc_water_factor(1, 1) == _calc_water_factor(1000, 1000)
234
229
 
235
230
 
231
+ def test_calc_water_factor_zero():
232
+ """
233
+ Closes issue 771. Function should not raise 0 error and should return the maximum water factor.
234
+ """
235
+ assert _calc_water_factor(0, 0) == 1.49961875
236
+
237
+
236
238
  # --- IPCC SOIL CATEGORY TESTS ---
237
239
 
238
240
 
@@ -300,11 +302,9 @@ LAND_USE_CATEGORY_PARAMS = [
300
302
  ids=[params[0] for params in LAND_USE_CATEGORY_PARAMS]
301
303
  )
302
304
  @patch(f"{class_path}.get_irrigated_terms", return_value=IRRIGATED_TERM_IDS)
303
- @patch(f"{class_path}.get_long_fallow_land_cover_terms", return_value=LONG_FALLOW_LAND_COVER_TERM_IDS)
304
305
  @patch(f"{class_path}.get_upland_rice_land_cover_terms", return_value=UPLAND_RICE_LAND_COVER_TERM_IDS)
305
306
  def test_assign_ipcc_land_use_category(
306
307
  _mock_get_upland_rice_land_cover_terms,
307
- _mock_get_long_fallow_land_cover_terms,
308
308
  _mock_get_irrigated_terms,
309
309
  subfolder,
310
310
  soil_category,
@@ -315,7 +315,7 @@ def test_assign_ipcc_land_use_category(
315
315
  with open(f"{folder}/site.jsonld", encoding='utf-8') as f:
316
316
  site = json.load(f)
317
317
 
318
- result = _assign_ipcc_land_use_category(site.get("siteType"), site.get("management", []), soil_category)
318
+ result = _assign_ipcc_land_use_category(site.get("management", []), soil_category)
319
319
  assert result == expected
320
320
 
321
321
 
@@ -363,11 +363,9 @@ def test_assign_ipcc_management_category(subfolder, land_use_category, expected)
363
363
  @patch(f"{class_path}.get_cover_crop_property_terms", return_value=COVER_CROP_PROPERTY_TERM_IDS)
364
364
  @patch(f"{class_path}.get_crop_residue_incorporated_or_left_on_field_terms", return_value=CROP_RESIDUE_INCORP_TERM_IDS)
365
365
  @patch(f"{class_path}.get_irrigated_terms", return_value=IRRIGATED_TERM_IDS)
366
- @patch(f"{class_path}.get_long_fallow_land_cover_terms", return_value=LONG_FALLOW_LAND_COVER_TERM_IDS)
367
366
  @patch(f"{class_path}.get_residue_removed_or_burnt_terms", return_value=RESIDUE_REMOVED_OR_BURNT_TERM_IDS)
368
367
  def test_check_cropland_medium_category(
369
368
  _mock_get_residue_removed_or_burnt_terms,
370
- _mock_get_long_fallow_land_cover_terms,
371
369
  _mock_get_irrigated_terms,
372
370
  _mock_get_crop_residue_incorporated_or_left_on_field_terms,
373
371
  _mock_get_cover_crop_property_terms,
@@ -390,11 +388,9 @@ def test_check_cropland_medium_category(
390
388
  @patch(f"{class_path}.get_cover_crop_property_terms", return_value=COVER_CROP_PROPERTY_TERM_IDS)
391
389
  @patch(f"{class_path}.get_crop_residue_incorporated_or_left_on_field_terms", return_value=CROP_RESIDUE_INCORP_TERM_IDS)
392
390
  @patch(f"{class_path}.get_irrigated_terms", return_value=IRRIGATED_TERM_IDS)
393
- @patch(f"{class_path}.get_long_fallow_land_cover_terms", return_value=LONG_FALLOW_LAND_COVER_TERM_IDS)
394
391
  @patch(f"{class_path}.get_residue_removed_or_burnt_terms", return_value=RESIDUE_REMOVED_OR_BURNT_TERM_IDS)
395
392
  def test_check_cropland_low_category(
396
393
  _mock_get_residue_removed_or_burnt_terms,
397
- _mock_get_long_fallow_land_cover_terms,
398
394
  _mock_get_irrigated_terms,
399
395
  _mock_get_crop_residue_incorporated_or_left_on_field_terms,
400
396
  _mock_get_cover_crop_property_terms,
@@ -459,11 +455,9 @@ CARBON_INPUT_CATEGORY_PARAMS = [
459
455
  @patch(f"{class_path}.get_cover_crop_property_terms", return_value=COVER_CROP_PROPERTY_TERM_IDS)
460
456
  @patch(f"{class_path}.get_crop_residue_incorporated_or_left_on_field_terms", return_value=CROP_RESIDUE_INCORP_TERM_IDS)
461
457
  @patch(f"{class_path}.get_irrigated_terms", return_value=IRRIGATED_TERM_IDS)
462
- @patch(f"{class_path}.get_long_fallow_land_cover_terms", return_value=LONG_FALLOW_LAND_COVER_TERM_IDS)
463
458
  @patch(f"{class_path}.get_residue_removed_or_burnt_terms", return_value=RESIDUE_REMOVED_OR_BURNT_TERM_IDS)
464
459
  def test_assign_ipcc_carbon_input_category(
465
460
  _mock_get_residue_removed_or_burnt_terms,
466
- _mock_get_long_fallow_land_cover_terms,
467
461
  _mock_get_irrigated_terms,
468
462
  _mock_get_crop_residue_incorporated_or_left_on_field_terms,
469
463
  _mock_get_cover_crop_property_terms,
@@ -0,0 +1,45 @@
1
+ from unittest.mock import patch
2
+ import json
3
+ from tests.utils import fixtures_path, fake_new_emission
4
+
5
+ from hestia_earth.models.schmidt2007.h2SToAirWasteTreatment import MODEL, TERM_ID, run, _should_run
6
+
7
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
8
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
9
+
10
+
11
+ @patch(f"{class_path}.get_waste_values")
12
+ def test_should_run(mock_get_waste_values):
13
+ # no fuel values => no run
14
+ mock_get_waste_values.return_value = []
15
+ should_run, *args = _should_run({})
16
+ assert not should_run
17
+
18
+ # with fuel values => run
19
+ mock_get_waste_values.return_value = [0]
20
+ should_run, *args = _should_run({})
21
+ assert should_run is True
22
+
23
+
24
+ @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
25
+ def test_run(*args):
26
+ with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
27
+ cycle = json.load(f)
28
+
29
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
30
+ expected = json.load(f)
31
+
32
+ value = run(cycle)
33
+ assert value == expected
34
+
35
+
36
+ @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
37
+ def test_run_data_complete(*args):
38
+ with open(f"{fixtures_folder}/no-input-data-complete/cycle.jsonld", encoding='utf-8') as f:
39
+ cycle = json.load(f)
40
+
41
+ with open(f"{fixtures_folder}/no-input-data-complete/result.jsonld", encoding='utf-8') as f:
42
+ expected = json.load(f)
43
+
44
+ value = run(cycle)
45
+ assert value == expected
@@ -0,0 +1,45 @@
1
+ from unittest.mock import patch
2
+ import json
3
+ from tests.utils import fixtures_path, fake_new_emission
4
+
5
+ from hestia_earth.models.schmidt2007.n2OToAirWasteTreatmentDirect import MODEL, TERM_ID, run, _should_run
6
+
7
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
8
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
9
+
10
+
11
+ @patch(f"{class_path}.get_waste_values")
12
+ def test_should_run(mock_get_waste_values):
13
+ # no fuel values => no run
14
+ mock_get_waste_values.return_value = []
15
+ should_run, *args = _should_run({})
16
+ assert not should_run
17
+
18
+ # with fuel values => run
19
+ mock_get_waste_values.return_value = [0]
20
+ should_run, *args = _should_run({})
21
+ assert should_run is True
22
+
23
+
24
+ @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
25
+ def test_run(*args):
26
+ with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
27
+ cycle = json.load(f)
28
+
29
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
30
+ expected = json.load(f)
31
+
32
+ value = run(cycle)
33
+ assert value == expected
34
+
35
+
36
+ @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
37
+ def test_run_data_complete(*args):
38
+ with open(f"{fixtures_folder}/no-input-data-complete/cycle.jsonld", encoding='utf-8') as f:
39
+ cycle = json.load(f)
40
+
41
+ with open(f"{fixtures_folder}/no-input-data-complete/result.jsonld", encoding='utf-8') as f:
42
+ expected = json.load(f)
43
+
44
+ value = run(cycle)
45
+ assert value == expected
@@ -0,0 +1,45 @@
1
+ from unittest.mock import patch
2
+ import json
3
+ from tests.utils import fixtures_path, fake_new_emission
4
+
5
+ from hestia_earth.models.schmidt2007.nh3ToAirWasteTreatment import MODEL, TERM_ID, run, _should_run
6
+
7
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
8
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
9
+
10
+
11
+ @patch(f"{class_path}.get_waste_values")
12
+ def test_should_run(mock_get_waste_values):
13
+ # no fuel values => no run
14
+ mock_get_waste_values.return_value = []
15
+ should_run, *args = _should_run({})
16
+ assert not should_run
17
+
18
+ # with fuel values => run
19
+ mock_get_waste_values.return_value = [0]
20
+ should_run, *args = _should_run({})
21
+ assert should_run is True
22
+
23
+
24
+ @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
25
+ def test_run(*args):
26
+ with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
27
+ cycle = json.load(f)
28
+
29
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
30
+ expected = json.load(f)
31
+
32
+ value = run(cycle)
33
+ assert value == expected
34
+
35
+
36
+ @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
37
+ def test_run_data_complete(*args):
38
+ with open(f"{fixtures_folder}/no-input-data-complete/cycle.jsonld", encoding='utf-8') as f:
39
+ cycle = json.load(f)
40
+
41
+ with open(f"{fixtures_folder}/no-input-data-complete/result.jsonld", encoding='utf-8') as f:
42
+ expected = json.load(f)
43
+
44
+ value = run(cycle)
45
+ assert value == expected
@@ -1,5 +1,7 @@
1
1
  import json
2
2
  from unittest.mock import patch
3
+
4
+ import pytest
3
5
  from hestia_earth.schema import TermTermType
4
6
 
5
7
  from hestia_earth.models.site.management import MODEL, MODEL_KEY, run, _should_run
@@ -13,6 +15,16 @@ TERM_BY_ID = {
13
15
  }
14
16
 
15
17
 
18
+ def lookup_side_effect(*args, **kwargs):
19
+ # Values taken from real lookups.
20
+ _ = kwargs
21
+ if args[0]["@id"] == "ureaKgN" and args[1] == "nitrogenContent":
22
+ return 45.5
23
+ if args[0]["@id"] == "compostKgMass" and args[1] == "ANIMAL_MANURE":
24
+ return False
25
+ return True
26
+
27
+
16
28
  @patch(f"{CLASS_PATH}.download_hestia", side_effect=lambda id, *args: TERM_BY_ID[id])
17
29
  @patch(f"{CLASS_PATH}.related_cycles")
18
30
  def test_should_run(mock_related_cycles, *args):
@@ -100,17 +112,26 @@ def test_should_run(mock_related_cycles, *args):
100
112
  }]
101
113
 
102
114
 
115
+ @pytest.mark.parametrize(
116
+ "test_name,fixture_path",
117
+ [
118
+ ("Example 1", f"{fixtures_folder}/inputs/example1"),
119
+ ("Example 2", f"{fixtures_folder}/inputs/example2"),
120
+ ("Example 3", f"{fixtures_folder}/inputs/example3")
121
+ ]
122
+ )
103
123
  @patch(f"{CLASS_PATH}.download_hestia", side_effect=lambda id, *args: TERM_BY_ID[id])
104
124
  @patch(f"{CLASS_PATH}.related_cycles")
105
- def test_run(mock_related_cycles, *args):
106
- with open(f"{fixtures_folder}/cycles.jsonld", encoding='utf-8') as f:
125
+ @patch(f"{CLASS_PATH}._get_lookup_with_debug", side_effect=lookup_side_effect)
126
+ def test_run(mock_get_lookup_with_debug, mock_related_cycles, mock_download, test_name, fixture_path):
127
+ with open(f"{fixture_path}/cycles.jsonld", encoding='utf-8') as f:
107
128
  cycles = json.load(f)
108
129
  mock_related_cycles.return_value = cycles
109
130
 
110
131
  with open(f"{fixtures_folder}/site.jsonld", encoding='utf-8') as f:
111
132
  site = json.load(f)
112
133
 
113
- with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
134
+ with open(f"{fixture_path}/result.jsonld", encoding='utf-8') as f:
114
135
  expected = json.load(f)
115
136
 
116
137
  result = run(site)
@@ -79,12 +79,12 @@ def test_harmonise_measurements(measurements_list, returns_dict, expected_value)
79
79
  (
80
80
  "missing dates => run",
81
81
  {
82
- "measurements":
83
- [
82
+ "measurements": [
84
83
  {
85
84
  "term": {"@id": "clayContent"},
86
85
  "depthUpper": 0,
87
- "depthLower": 20
86
+ "depthLower": 20,
87
+ "value": [0]
88
88
  }
89
89
  ]
90
90
  },
@@ -93,29 +93,43 @@ def test_harmonise_measurements(measurements_list, returns_dict, expected_value)
93
93
  (
94
94
  "no depthUpper => no run",
95
95
  {
96
- "measurements":
97
- [
98
- {
99
- "term": {"@id": "clayContent"},
100
- "dates": ["2022-01-02"],
101
- "depthLower": 20
102
- }
103
- ]
96
+ "measurements": [
97
+ {
98
+ "term": {"@id": "clayContent"},
99
+ "dates": ["2022-01-02"],
100
+ "depthLower": 20,
101
+ "value": [0]
102
+ }
103
+ ]
104
+ },
105
+ False
106
+ ),
107
+ (
108
+ "missing value => not run",
109
+ {
110
+ "measurements": [
111
+ {
112
+ "term": {"@id": "clayContent"},
113
+ "dates": ["2022-01-02"],
114
+ "depthUpper": 0,
115
+ "depthLower": 20
116
+ }
117
+ ]
104
118
  },
105
119
  False
106
120
  ),
107
121
  (
108
122
  "all fields => run",
109
123
  {
110
- "measurements":
111
- [
112
- {
113
- "term": {"@id": "clayContent"},
114
- "dates": ["2022-01-02"],
115
- "depthUpper": 0,
116
- "depthLower": 20
117
- }
118
- ]
124
+ "measurements": [
125
+ {
126
+ "term": {"@id": "clayContent"},
127
+ "dates": ["2022-01-02"],
128
+ "depthUpper": 0,
129
+ "depthLower": 20,
130
+ "value": [0]
131
+ }
132
+ ]
119
133
  },
120
134
  True
121
135
  )
@@ -141,7 +155,12 @@ def lookup_side_effect(*args, **kwargs):
141
155
  @pytest.mark.parametrize(
142
156
  "test_name",
143
157
  [
144
- "missingDepth", "simpleSoilPh", "clayContent", "missingDepth", "nonUniqueMeasurements", "arrays"
158
+ "missing-depth",
159
+ "missing-value",
160
+ "simple-soilPh",
161
+ "clayContent",
162
+ "non-unique-measurements",
163
+ "arrays"
145
164
  ]
146
165
  )
147
166
  @patch(f"{class_path}._new_measurement", side_effect=fake_new_measurement)