| 
									
										
										
										
											2022-01-13 13:06:52 -09:00
										 |  |  |  | import shutil | 
					
						
							| 
									
										
										
										
											2021-10-09 13:08:23 -08:00
										 |  |  |  | from dataclasses import dataclass | 
					
						
							|  |  |  |  | from fractions import Fraction | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | import pytest | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-16 16:06:13 -08:00
										 |  |  |  | from mealie.services.parser_services import RegisteredParser, get_parser | 
					
						
							| 
									
										
										
										
											2021-10-09 13:08:23 -08:00
										 |  |  |  | from mealie.services.parser_services.crfpp.processor import CRFIngredient, convert_list_to_crf_model | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | @dataclass | 
					
						
							|  |  |  |  | class TestIngredient: | 
					
						
							|  |  |  |  |     input: str | 
					
						
							|  |  |  |  |     quantity: float | 
					
						
							|  |  |  |  |     unit: str | 
					
						
							|  |  |  |  |     food: str | 
					
						
							|  |  |  |  |     comments: str | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-16 16:06:13 -08:00
										 |  |  |  | def crf_exists() -> bool: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return shutil.which("crf_test") is not None | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-09 13:08:23 -08:00
										 |  |  |  | # TODO - add more robust test cases | 
					
						
							|  |  |  |  | test_ingredients = [ | 
					
						
							|  |  |  |  |     TestIngredient("½ cup all-purpose flour", 0.5, "cup", "all-purpose flour", ""), | 
					
						
							|  |  |  |  |     TestIngredient("1 ½ teaspoons ground black pepper", 1.5, "teaspoon", "black pepper", "ground"), | 
					
						
							|  |  |  |  |     TestIngredient("⅔ cup unsweetened flaked coconut", 0.7, "cup", "coconut", "unsweetened flaked"), | 
					
						
							|  |  |  |  |     TestIngredient("⅓ cup panko bread crumbs", 0.3, "cup", "panko bread crumbs", ""), | 
					
						
							|  |  |  |  | ] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | @pytest.mark.skipif(not crf_exists(), reason="CRF++ not installed") | 
					
						
							|  |  |  |  | def test_nlp_parser(): | 
					
						
							|  |  |  |  |     models: list[CRFIngredient] = convert_list_to_crf_model([x.input for x in test_ingredients]) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # Itterate over mdoels and test_ingreidnets to gether | 
					
						
							|  |  |  |  |     for model, test_ingredient in zip(models, test_ingredients): | 
					
						
							|  |  |  |  |         assert float(sum(Fraction(s) for s in model.qty.split())) == test_ingredient.quantity | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         assert model.comment == test_ingredient.comments | 
					
						
							|  |  |  |  |         assert model.name == test_ingredient.food | 
					
						
							|  |  |  |  |         assert model.unit == test_ingredient.unit | 
					
						
							| 
									
										
										
										
											2021-10-16 16:06:13 -08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | def test_brute_parser(): | 
					
						
							|  |  |  |  |     # input: (quantity, unit, food, comments) | 
					
						
							|  |  |  |  |     expectations = { | 
					
						
							|  |  |  |  |         # Dutch | 
					
						
							|  |  |  |  |         "1 theelepel koffie": (1, "theelepel", "koffie", ""), | 
					
						
							|  |  |  |  |         "3 theelepels koffie": (3, "theelepels", "koffie", ""), | 
					
						
							|  |  |  |  |         "1 eetlepel tarwe": (1, "eetlepel", "tarwe", ""), | 
					
						
							|  |  |  |  |         "20 eetlepels bloem": (20, "eetlepels", "bloem", ""), | 
					
						
							|  |  |  |  |         "1 mespunt kaneel": (1, "mespunt", "kaneel", ""), | 
					
						
							|  |  |  |  |         "1 snuf(je) zout": (1, "snuf(je)", "zout", ""), | 
					
						
							|  |  |  |  |         "2 tbsp minced cilantro, leaves and stems": (2, "tbsp", "minced cilantro", "leaves and stems"), | 
					
						
							|  |  |  |  |         "1 large yellow onion, coarsely chopped": (1, "large", "yellow onion", "coarsely chopped"), | 
					
						
							|  |  |  |  |         "1 1/2 tsp garam masala": (1.5, "tsp", "garam masala", ""), | 
					
						
							|  |  |  |  |         "2 cups mango chunks, (2 large mangoes) (fresh or frozen)": ( | 
					
						
							|  |  |  |  |             2, | 
					
						
							|  |  |  |  |             "cups", | 
					
						
							|  |  |  |  |             "mango chunks, (2 large mangoes)", | 
					
						
							|  |  |  |  |             "fresh or frozen", | 
					
						
							|  |  |  |  |         ), | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     parser = get_parser(RegisteredParser.brute) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     for key, val in expectations.items(): | 
					
						
							|  |  |  |  |         parsed = parser.parse_one(key) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         assert parsed.ingredient.quantity == val[0] | 
					
						
							|  |  |  |  |         assert parsed.ingredient.unit.name == val[1] | 
					
						
							|  |  |  |  |         assert parsed.ingredient.food.name == val[2] | 
					
						
							|  |  |  |  |         assert parsed.ingredient.note in {val[3], None} |