From 955506e548c4cbde5adcf7c40513ceb039ec76d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Gigandet?= Date: Wed, 11 Oct 2023 15:27:15 +0200 Subject: [PATCH] fix: milk, dairy drinks and plant-based beverages Nutri-Score 2023 (#9141) In the new Nutri-Score formula, milk, dairy drinks and dairy drinks substitutes are considered beverages. --- lib/ProductOpener/Config_off.pm | 30 ++- lib/ProductOpener/Food.pm | 62 ++++- lib/ProductOpener/FoodGroups.pm | 2 +- .../beverage-with-80-percent-milk.json | 29 +-- .../dairy-drink-with-80-percent-milk.json | 29 +-- .../nutriscore/en-milk.json | 204 ++++++++++++++++ .../fr-plant-beverages-soy-milk.json | 221 ++++++++++++++++++ .../nutriscore/milk.json | 29 +-- tests/unit/nutriscore.t | 34 +++ 9 files changed, 588 insertions(+), 52 deletions(-) create mode 100644 tests/unit/expected_test_results/nutriscore/en-milk.json create mode 100644 tests/unit/expected_test_results/nutriscore/fr-plant-beverages-soy-milk.json diff --git a/lib/ProductOpener/Config_off.pm b/lib/ProductOpener/Config_off.pm index 985c014d5227f..a4173855f8a76 100644 --- a/lib/ProductOpener/Config_off.pm +++ b/lib/ProductOpener/Config_off.pm @@ -487,7 +487,7 @@ XML ; # Nutriscore: categories that are never considered beverages for Nutri-Score computation -$options{categories_not_considered_as_beverages_for_nutriscore} = [ +$options{categories_not_considered_as_beverages_for_nutriscore_2021} = [ qw( en:plant-milks en:milks @@ -498,16 +498,40 @@ $options{categories_not_considered_as_beverages_for_nutriscore} = [ ) ]; -# categories that are considered as beverages +$options{categories_not_considered_as_beverages_for_nutriscore_2023} = [ + qw( + en:meal-replacement + en:soups + ) +]; + +# categories that are considered as beverages for Nutri-Score 2021 # unless they have 80% milk (which we will determine through ingredients analysis) -$options{categories_considered_as_beverages_for_nutriscore} = [ +$options{categories_considered_as_beverages_for_nutriscore_2021} = [ qw( en:tea-based-beverages en:iced-teas en:herbal-tea-beverages en:coffee-beverages en:coffee-drinks + en:coffees + en:herbal-teas + en:teas + ) +]; +# categories that are considered as beverages for Nutri-Score 2023 +$options{categories_considered_as_beverages_for_nutriscore_2023} = [ + qw( + en:milks + en:dairy-drinks-substitutes + en:dairy-drinks + en:plant-based-beverages + en:tea-based-beverages + en:iced-teas + en:herbal-tea-beverages + en:coffee-beverages + en:coffee-drinks en:coffees en:herbal-teas en:teas diff --git a/lib/ProductOpener/Food.pm b/lib/ProductOpener/Food.pm index e0c043dd5a42f..96b92a8628dc2 100644 --- a/lib/ProductOpener/Food.pm +++ b/lib/ProductOpener/Food.pm @@ -59,7 +59,8 @@ BEGIN { &fix_salt_equivalent - &is_beverage_for_nutrition_score + &is_beverage_for_nutrition_score_2021 + &is_beverage_for_nutrition_score_2023 &is_water_for_nutrition_score &is_cheese_for_nutrition_score &is_fat_for_nutrition_score @@ -800,16 +801,16 @@ sub canonicalize_nutriment ($target_lc, $nutrient) { return $nid; } -=head2 is_beverage_for_nutrition_score( $product_ref ) +=head2 is_beverage_for_nutrition_score_2021 ( $product_ref ) Determines if a product should be considered as a beverage for Nutri-Score computations, based on the product categories. -Dairy drinks are not considered as beverages if they have at least 80% of milk. +2021 Nutri-Score: Dairy drinks are not considered as beverages if they have at least 80% of milk. =cut -sub is_beverage_for_nutrition_score ($product_ref) { +sub is_beverage_for_nutrition_score_2021 ($product_ref) { my $is_beverage = 0; @@ -817,9 +818,9 @@ sub is_beverage_for_nutrition_score ($product_ref) { $is_beverage = 1; - if (defined $options{categories_not_considered_as_beverages_for_nutriscore}) { + if (defined $options{categories_not_considered_as_beverages_for_nutriscore_2021}) { - foreach my $category_id (@{$options{categories_not_considered_as_beverages_for_nutriscore}}) { + foreach my $category_id (@{$options{categories_not_considered_as_beverages_for_nutriscore_2021}}) { if (has_tag($product_ref, "categories", $category_id)) { $is_beverage = 0; @@ -829,8 +830,8 @@ sub is_beverage_for_nutrition_score ($product_ref) { } # exceptions - if (defined $options{categories_considered_as_beverages_for_nutriscore}) { - foreach my $category_id (@{$options{categories_considered_as_beverages_for_nutriscore}}) { + if (defined $options{categories_considered_as_beverages_for_nutriscore_2021}) { + foreach my $category_id (@{$options{categories_considered_as_beverages_for_nutriscore_2021}}) { if (has_tag($product_ref, "categories", $category_id)) { $is_beverage = 1; @@ -851,6 +852,49 @@ sub is_beverage_for_nutrition_score ($product_ref) { return $is_beverage; } +=head2 is_beverage_for_nutrition_score_2023 ( $product_ref ) + +Determines if a product should be considered as a beverage for Nutri-Score computations, +based on the product categories. + +2023 Nutri-Score: Milk and dairy drinks are considered beverages. + +=cut + +sub is_beverage_for_nutrition_score_2023 ($product_ref) { + + my $is_beverage = 0; + + if (has_tag($product_ref, "categories", "en:beverages")) { + + $is_beverage = 1; + + if (defined $options{categories_not_considered_as_beverages_for_nutriscore_2023}) { + + foreach my $category_id (@{$options{categories_not_considered_as_beverages_for_nutriscore_2023}}) { + + if (has_tag($product_ref, "categories", $category_id)) { + $is_beverage = 0; + last; + } + } + } + } + + # exceptions + if (defined $options{categories_considered_as_beverages_for_nutriscore_2023}) { + foreach my $category_id (@{$options{categories_considered_as_beverages_for_nutriscore_2023}}) { + + if (has_tag($product_ref, "categories", $category_id)) { + $is_beverage = 1; + last; + } + } + } + + return $is_beverage; +} + =head2 is_water_for_nutrition_score( $product_ref ) Determines if a product should be considered as water for Nutri-Score computations, @@ -1417,7 +1461,7 @@ sub compute_nutriscore_data ($product_ref, $prepared, $nutriments_field, $versio my $fruits_vegetables_legumes = compute_nutriscore_2023_fruits_vegetables_legumes($product_ref, $prepared); my $is_fat_oil_nuts_seeds = is_fat_oil_nuts_seeds_for_nutrition_score($product_ref); - my $is_beverage = $product_ref->{nutrition_score_beverage}; + my $is_beverage = is_beverage_for_nutrition_score_2023($product_ref); $nutriscore_data_ref = { is_beverage => $is_beverage, diff --git a/lib/ProductOpener/FoodGroups.pm b/lib/ProductOpener/FoodGroups.pm index 54b61dc545709..222aeb4ac0523 100644 --- a/lib/ProductOpener/FoodGroups.pm +++ b/lib/ProductOpener/FoodGroups.pm @@ -234,7 +234,7 @@ All levels food groups are stored in $product_ref->{food_groups_tags} sub compute_food_groups ($product_ref) { - $product_ref->{nutrition_score_beverage} = is_beverage_for_nutrition_score($product_ref); + $product_ref->{nutrition_score_beverage} = is_beverage_for_nutrition_score_2021($product_ref); # Temporarily change categories (backup old one in original_categories_tags) temporarily_change_categories_for_food_groups_computation($product_ref); diff --git a/tests/unit/expected_test_results/nutriscore/beverage-with-80-percent-milk.json b/tests/unit/expected_test_results/nutriscore/beverage-with-80-percent-milk.json index 3a39b9b890dc9..5b2306c204e96 100644 --- a/tests/unit/expected_test_results/nutriscore/beverage-with-80-percent-milk.json +++ b/tests/unit/expected_test_results/nutriscore/beverage-with-80-percent-milk.json @@ -103,8 +103,9 @@ "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", "en:nutrition-all-nutriscore-values-known", "en:nutrition-fruits-vegetables-legumes-estimate-from-ingredients", - "en:nutriscore-2021-same-as-2023", - "en:nutriscore-2021-d-2023-d" + "en:nutriscore-2021-different-from-2023", + "en:nutriscore-2021-better-than-2023", + "en:nutriscore-2021-d-2023-e" ], "nucleotides_tags" : [], "nutriments" : { @@ -168,15 +169,15 @@ "2023" : { "category_available" : 1, "data" : { - "count_proteins" : 0, - "count_proteins_reason" : "negative_points_more_than_11", + "count_proteins" : 1, + "count_proteins_reason" : "beverage", "energy" : 3378, "energy_points" : 10, "fiber" : 2, "fiber_points" : 0, "fruits_vegetables_legumes" : 0, "fruits_vegetables_legumes_points" : 0, - "is_beverage" : 0, + "is_beverage" : 1, "is_cheese" : 0, "is_fat_oil_nuts_seeds" : 0, "is_red_meat_product" : 0, @@ -188,33 +189,35 @@ "salt", "non_nutritive_sweeteners" ], - "negative_points" : 16, + "negative_points" : 22, + "non_nutritive_sweeteners_points" : 0, "positive_nutrients" : [ "fruits_vegetables_legumes", - "fiber" + "fiber", + "proteins" ], - "positive_points" : 0, + "positive_points" : 7, "proteins" : 5, - "proteins_points" : 2, + "proteins_points" : 7, "salt" : 0, "salt_points" : 0, "saturated_fat" : 5, "saturated_fat_points" : 4, "sugars" : 10, - "sugars_points" : 2 + "sugars_points" : 8 }, - "grade" : "d", + "grade" : "e", "nutrients_available" : 1, "nutriscore_applicable" : 1, "nutriscore_computed" : 1, - "score" : 16 + "score" : 15 } }, "nutriscore_2021_tags" : [ "d" ], "nutriscore_2023_tags" : [ - "d" + "e" ], "nutriscore_data" : { "energy" : 3378, diff --git a/tests/unit/expected_test_results/nutriscore/dairy-drink-with-80-percent-milk.json b/tests/unit/expected_test_results/nutriscore/dairy-drink-with-80-percent-milk.json index ecda62c5fc835..d36013fd82ad6 100644 --- a/tests/unit/expected_test_results/nutriscore/dairy-drink-with-80-percent-milk.json +++ b/tests/unit/expected_test_results/nutriscore/dairy-drink-with-80-percent-milk.json @@ -111,8 +111,9 @@ "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", "en:nutrition-all-nutriscore-values-known", "en:nutrition-fruits-vegetables-legumes-estimate-from-ingredients", - "en:nutriscore-2021-same-as-2023", - "en:nutriscore-2021-d-2023-d" + "en:nutriscore-2021-different-from-2023", + "en:nutriscore-2021-better-than-2023", + "en:nutriscore-2021-d-2023-e" ], "nucleotides_tags" : [], "nutriments" : { @@ -176,15 +177,15 @@ "2023" : { "category_available" : 1, "data" : { - "count_proteins" : 0, - "count_proteins_reason" : "negative_points_more_than_11", + "count_proteins" : 1, + "count_proteins_reason" : "beverage", "energy" : 3378, "energy_points" : 10, "fiber" : 2, "fiber_points" : 0, "fruits_vegetables_legumes" : 0, "fruits_vegetables_legumes_points" : 0, - "is_beverage" : 0, + "is_beverage" : 1, "is_cheese" : 0, "is_fat_oil_nuts_seeds" : 0, "is_red_meat_product" : 0, @@ -196,33 +197,35 @@ "salt", "non_nutritive_sweeteners" ], - "negative_points" : 16, + "negative_points" : 22, + "non_nutritive_sweeteners_points" : 0, "positive_nutrients" : [ "fruits_vegetables_legumes", - "fiber" + "fiber", + "proteins" ], - "positive_points" : 0, + "positive_points" : 7, "proteins" : 5, - "proteins_points" : 2, + "proteins_points" : 7, "salt" : 0, "salt_points" : 0, "saturated_fat" : 5, "saturated_fat_points" : 4, "sugars" : 10, - "sugars_points" : 2 + "sugars_points" : 8 }, - "grade" : "d", + "grade" : "e", "nutrients_available" : 1, "nutriscore_applicable" : 1, "nutriscore_computed" : 1, - "score" : 16 + "score" : 15 } }, "nutriscore_2021_tags" : [ "d" ], "nutriscore_2023_tags" : [ - "d" + "e" ], "nutriscore_data" : { "energy" : 3378, diff --git a/tests/unit/expected_test_results/nutriscore/en-milk.json b/tests/unit/expected_test_results/nutriscore/en-milk.json new file mode 100644 index 0000000000000..2ba2a7d3df8b4 --- /dev/null +++ b/tests/unit/expected_test_results/nutriscore/en-milk.json @@ -0,0 +1,204 @@ +{ + "categories" : "milk", + "categories_hierarchy" : [ + "en:dairies", + "en:milks" + ], + "categories_lc" : "en", + "categories_properties" : { + "agribalyse_proxy_food_code:en" : "19041" + }, + "categories_properties_tags" : [ + "all-products", + "categories-known", + "agribalyse-food-code-unknown", + "agribalyse-proxy-food-code-19041", + "agribalyse-proxy-food-code-known", + "ciqual-food-code-unknown", + "agribalyse-known", + "agribalyse-19041" + ], + "categories_tags" : [ + "en:dairies", + "en:milks" + ], + "food_groups" : "en:milk-and-yogurt", + "food_groups_tags" : [ + "en:milk-and-dairy-products", + "en:milk-and-yogurt" + ], + "lc" : "en", + "misc_tags" : [ + "en:nutrition-no-fiber", + "en:nutriscore-computed", + "en:nutrition-no-fruits-vegetables-nuts", + "en:nutrition-no-fiber-or-fruits-vegetables-nuts", + "en:nutriscore-2021-different-from-2023", + "en:nutriscore-2021-better-than-2023", + "en:nutriscore-2021-a-2023-b" + ], + "nutriments" : { + "energy_100g" : 195, + "fat_100g" : 1.6, + "nutrition-score-fr" : -1, + "nutrition-score-fr_100g" : -1, + "proteins_100g" : 3.3, + "salt_100g" : 0.1, + "salt_value" : 0.1, + "saturated-fat_100g" : 1, + "sodium" : 0.04, + "sodium_100g" : 0.04, + "sodium_unit" : "g", + "sodium_value" : 0.04, + "sugars_100g" : 4.8 + }, + "nutriscore" : { + "2021" : { + "category_available" : 1, + "data" : { + "energy" : 195, + "energy_points" : 0, + "energy_value" : 195, + "fiber" : 0, + "fiber_points" : 0, + "fiber_value" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 0, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "negative_points" : 1, + "positive_points" : 2, + "proteins" : 3.3, + "proteins_points" : 2, + "proteins_value" : 3.3, + "saturated_fat" : 1, + "saturated_fat_points" : 0, + "saturated_fat_value" : 1, + "sodium" : 40, + "sodium_points" : 0, + "sodium_value" : 40, + "sugars" : 4.8, + "sugars_points" : 1, + "sugars_value" : 4.8 + }, + "grade" : "a", + "nutrients_available" : 1, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 1, + "score" : -1 + }, + "2023" : { + "category_available" : 1, + "data" : { + "count_proteins" : 1, + "count_proteins_reason" : "beverage", + "energy" : 195, + "energy_points" : 3, + "fiber" : 0, + "fiber_points" : 0, + "fruits_vegetables_legumes" : null, + "is_beverage" : 1, + "is_cheese" : 0, + "is_fat_oil_nuts_seeds" : 0, + "is_red_meat_product" : 0, + "is_water" : 0, + "negative_nutrients" : [ + "energy", + "sugars", + "saturated_fat", + "salt", + "non_nutritive_sweeteners" + ], + "negative_points" : 6, + "non_nutritive_sweeteners_points" : 0, + "positive_nutrients" : [ + "fruits_vegetables_legumes", + "fiber", + "proteins" + ], + "positive_points" : 7, + "proteins" : 3.3, + "proteins_points" : 7, + "salt" : 0.1, + "salt_points" : 0, + "saturated_fat" : 1, + "saturated_fat_points" : 0, + "sugars" : 4.8, + "sugars_points" : 3 + }, + "grade" : "b", + "nutrients_available" : 1, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 1, + "score" : -1 + } + }, + "nutriscore_2021_tags" : [ + "a" + ], + "nutriscore_2023_tags" : [ + "b" + ], + "nutriscore_data" : { + "energy" : 195, + "energy_points" : 0, + "energy_value" : 195, + "fiber" : 0, + "fiber_points" : 0, + "fiber_value" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 0, + "grade" : "a", + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "negative_points" : 1, + "positive_points" : 2, + "proteins" : 3.3, + "proteins_points" : 2, + "proteins_value" : 3.3, + "saturated_fat" : 1, + "saturated_fat_points" : 0, + "saturated_fat_value" : 1, + "score" : -1, + "sodium" : 40, + "sodium_points" : 0, + "sodium_value" : 40, + "sugars" : 4.8, + "sugars_points" : 1, + "sugars_value" : 4.8 + }, + "nutriscore_grade" : "a", + "nutriscore_score" : -1, + "nutriscore_score_opposite" : 1, + "nutriscore_tags" : [ + "a" + ], + "nutriscore_version" : "2021", + "nutrition_data_per" : "100g", + "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "a", + "nutrition_grades" : "a", + "nutrition_grades_tags" : [ + "a" + ], + "nutrition_score_beverage" : 0, + "nutrition_score_debug" : "", + "nutrition_score_warning_no_fiber" : 1, + "nutrition_score_warning_no_fruits_vegetables_nuts" : 1, + "pnns_groups_1" : "Milk and dairy products", + "pnns_groups_1_tags" : [ + "milk-and-dairy-products", + "known" + ], + "pnns_groups_2" : "Milk and yogurt", + "pnns_groups_2_tags" : [ + "milk-and-yogurt", + "known" + ] +} diff --git a/tests/unit/expected_test_results/nutriscore/fr-plant-beverages-soy-milk.json b/tests/unit/expected_test_results/nutriscore/fr-plant-beverages-soy-milk.json new file mode 100644 index 0000000000000..b0e95ab979d68 --- /dev/null +++ b/tests/unit/expected_test_results/nutriscore/fr-plant-beverages-soy-milk.json @@ -0,0 +1,221 @@ +{ + "categories" : "boissons végétales de soja", + "categories_hierarchy" : [ + "en:plant-based-foods-and-beverages", + "en:beverages", + "en:plant-based-foods", + "en:legumes-and-their-products", + "en:dairy-substitutes", + "en:plant-based-beverages", + "en:milk-substitutes", + "en:plant-milks", + "en:legume-milks", + "en:soy-milks" + ], + "categories_lc" : "fr", + "categories_properties" : { + "agribalyse_food_code:en" : "18900", + "ciqual_food_code:en" : "18900" + }, + "categories_properties_tags" : [ + "all-products", + "categories-known", + "agribalyse-food-code-18900", + "agribalyse-food-code-known", + "agribalyse-proxy-food-code-unknown", + "ciqual-food-code-18900", + "ciqual-food-code-known", + "agribalyse-known", + "agribalyse-18900" + ], + "categories_tags" : [ + "en:plant-based-foods-and-beverages", + "en:beverages", + "en:plant-based-foods", + "en:legumes-and-their-products", + "en:dairy-substitutes", + "en:plant-based-beverages", + "en:milk-substitutes", + "en:plant-milks", + "en:legume-milks", + "en:soy-milks" + ], + "food_groups" : "en:plant-based-milk-substitutes", + "food_groups_tags" : [ + "en:beverages", + "en:plant-based-milk-substitutes" + ], + "lc" : "fr", + "misc_tags" : [ + "en:nutriscore-computed", + "en:nutrition-no-fruits-vegetables-nuts", + "en:nutrition-no-fiber-or-fruits-vegetables-nuts", + "en:nutriscore-2021-different-from-2023", + "en:nutriscore-2021-better-than-2023", + "en:nutriscore-2021-a-2023-b" + ], + "nutriments" : { + "energy_100g" : 178, + "fat_100g" : 2.6, + "fiber_100g" : 0.5, + "nutrition-score-fr" : -2, + "nutrition-score-fr_100g" : -2, + "proteins_100g" : 3.9, + "salt_100g" : 0.03, + "salt_value" : 0.03, + "saturated-fat_100g" : 0.6, + "sodium" : 0.012, + "sodium_100g" : 0.012, + "sodium_unit" : "g", + "sodium_value" : 0.012, + "sugars_100g" : 0.5 + }, + "nutriscore" : { + "2021" : { + "category_available" : 1, + "data" : { + "energy" : 178, + "energy_points" : 0, + "energy_value" : 178, + "fiber" : 0.5, + "fiber_points" : 0, + "fiber_value" : 0.5, + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 0, + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "negative_points" : 0, + "positive_points" : 2, + "proteins" : 3.9, + "proteins_points" : 2, + "proteins_value" : 3.9, + "saturated_fat" : 0.6, + "saturated_fat_points" : 0, + "saturated_fat_value" : 0.6, + "sodium" : 12, + "sodium_points" : 0, + "sodium_value" : 12, + "sugars" : 0.5, + "sugars_points" : 0, + "sugars_value" : 0.5 + }, + "grade" : "a", + "nutrients_available" : 1, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 1, + "score" : -2 + }, + "2023" : { + "category_available" : 1, + "data" : { + "count_proteins" : 1, + "count_proteins_reason" : "beverage", + "energy" : 178, + "energy_points" : 3, + "fiber" : 0.5, + "fiber_points" : 0, + "fruits_vegetables_legumes" : null, + "is_beverage" : 1, + "is_cheese" : 0, + "is_fat_oil_nuts_seeds" : 0, + "is_red_meat_product" : 0, + "is_water" : 0, + "negative_nutrients" : [ + "energy", + "sugars", + "saturated_fat", + "salt", + "non_nutritive_sweeteners" + ], + "negative_points" : 3, + "non_nutritive_sweeteners_points" : 0, + "positive_nutrients" : [ + "fruits_vegetables_legumes", + "fiber", + "proteins" + ], + "positive_points" : 7, + "proteins" : 3.9, + "proteins_points" : 7, + "salt" : 0.03, + "salt_points" : 0, + "saturated_fat" : 0.6, + "saturated_fat_points" : 0, + "sugars" : 0.5, + "sugars_points" : 0 + }, + "grade" : "b", + "nutrients_available" : 1, + "nutriscore_applicable" : 1, + "nutriscore_computed" : 1, + "score" : -4 + } + }, + "nutriscore_2021_tags" : [ + "a" + ], + "nutriscore_2023_tags" : [ + "b" + ], + "nutriscore_data" : { + "energy" : 178, + "energy_points" : 0, + "energy_value" : 178, + "fiber" : 0.5, + "fiber_points" : 0, + "fiber_value" : 0.5, + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 0, + "grade" : "a", + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "negative_points" : 0, + "positive_points" : 2, + "proteins" : 3.9, + "proteins_points" : 2, + "proteins_value" : 3.9, + "saturated_fat" : 0.6, + "saturated_fat_points" : 0, + "saturated_fat_value" : 0.6, + "score" : -2, + "sodium" : 12, + "sodium_points" : 0, + "sodium_value" : 12, + "sugars" : 0.5, + "sugars_points" : 0, + "sugars_value" : 0.5 + }, + "nutriscore_grade" : "a", + "nutriscore_score" : -2, + "nutriscore_score_opposite" : 2, + "nutriscore_tags" : [ + "a" + ], + "nutriscore_version" : "2021", + "nutrition_data_per" : "100g", + "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "a", + "nutrition_grades" : "a", + "nutrition_grades_tags" : [ + "a" + ], + "nutrition_score_beverage" : 0, + "nutrition_score_debug" : "", + "nutrition_score_warning_no_fruits_vegetables_nuts" : 1, + "pnns_groups_1" : "Beverages", + "pnns_groups_1_tags" : [ + "beverages", + "known" + ], + "pnns_groups_2" : "Plant-based milk substitutes", + "pnns_groups_2_tags" : [ + "plant-based-milk-substitutes", + "known" + ] +} diff --git a/tests/unit/expected_test_results/nutriscore/milk.json b/tests/unit/expected_test_results/nutriscore/milk.json index a19a2a6a1e7ec..62b1e3dedeede 100644 --- a/tests/unit/expected_test_results/nutriscore/milk.json +++ b/tests/unit/expected_test_results/nutriscore/milk.json @@ -93,8 +93,9 @@ "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", "en:nutrition-all-nutriscore-values-known", "en:nutrition-fruits-vegetables-legumes-estimate-from-ingredients", - "en:nutriscore-2021-same-as-2023", - "en:nutriscore-2021-d-2023-d" + "en:nutriscore-2021-different-from-2023", + "en:nutriscore-2021-better-than-2023", + "en:nutriscore-2021-d-2023-e" ], "nucleotides_tags" : [], "nutriments" : { @@ -158,15 +159,15 @@ "2023" : { "category_available" : 1, "data" : { - "count_proteins" : 0, - "count_proteins_reason" : "negative_points_more_than_11", + "count_proteins" : 1, + "count_proteins_reason" : "beverage", "energy" : 3378, "energy_points" : 10, "fiber" : 2, "fiber_points" : 0, "fruits_vegetables_legumes" : 0, "fruits_vegetables_legumes_points" : 0, - "is_beverage" : 0, + "is_beverage" : 1, "is_cheese" : 0, "is_fat_oil_nuts_seeds" : 0, "is_red_meat_product" : 0, @@ -178,33 +179,35 @@ "salt", "non_nutritive_sweeteners" ], - "negative_points" : 16, + "negative_points" : 22, + "non_nutritive_sweeteners_points" : 0, "positive_nutrients" : [ "fruits_vegetables_legumes", - "fiber" + "fiber", + "proteins" ], - "positive_points" : 0, + "positive_points" : 7, "proteins" : 5, - "proteins_points" : 2, + "proteins_points" : 7, "salt" : 0, "salt_points" : 0, "saturated_fat" : 5, "saturated_fat_points" : 4, "sugars" : 10, - "sugars_points" : 2 + "sugars_points" : 8 }, - "grade" : "d", + "grade" : "e", "nutrients_available" : 1, "nutriscore_applicable" : 1, "nutriscore_computed" : 1, - "score" : 16 + "score" : 15 } }, "nutriscore_2021_tags" : [ "d" ], "nutriscore_2023_tags" : [ - "d" + "e" ], "nutriscore_data" : { "energy" : 3378, diff --git a/tests/unit/nutriscore.t b/tests/unit/nutriscore.t index 96add985583c9..91d246b32406c 100644 --- a/tests/unit/nutriscore.t +++ b/tests/unit/nutriscore.t @@ -627,6 +627,40 @@ my @tests = ( }, } ], + # Milk: considered a beverage in 2023 Nutri-Score + [ + "en-milk", + { + lc => "en", + categories => "milk", + nutriments => { + energy_100g => 195, + fat_100g => 1.6, + "saturated-fat_100g" => 1, + sugars_100g => 4.8, + salt_100g => 0.1, + proteins_100g => 3.3, + }, + } + ], + # Plant beverages: considered a beverage in 2023 Nutri-Score + [ + "fr-plant-beverages-soy-milk", + { + lc => "fr", + categories => "boissons végétales de soja", + ingredients => "Eau, fèves de soja 8%", + nutriments => { + energy_100g => 178, + fat_100g => 2.6, + "saturated-fat_100g" => 0.6, + sugars_100g => 0.5, + salt_100g => 0.03, + fiber_100g => 0.5, + proteins_100g => 3.9, + }, + } + ], );