File size: 3,065 Bytes
f8381b8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""Smoke tests for the PuLP-backed QuantitiesFinder.

Pure deterministic tool — no LLM, no network. Should be the fastest test in
the suite and the one we trust most.
"""

from __future__ import annotations

import json

from tools import QuantitiesFinder


def test_basic_two_food_balance() -> None:
    """Two foods, simple targets — solver must find quantities within a few
    percent of the target."""
    qf = QuantitiesFinder()
    payload = {
        "foods": [
            {
                "name": "chicken_breast",
                "calories": 165,
                "protein": 31,
                "fat": 3.6,
                "carbohydrates": 0,
                "estimated_g": 200,
            },
            {
                "name": "rice_cooked",
                "calories": 130,
                "protein": 2.7,
                "fat": 0.3,
                "carbohydrates": 28,
                "estimated_g": 200,
            },
        ],
        "targets": {"calories": 700, "protein": 65, "fat": 8, "carbohydrates": 60},
    }
    result = json.loads(qf.handle_task(json.dumps(payload)))
    assert "quantities" in result and "achieved" in result, f"Bad shape: {result}"

    achieved = result["achieved"]
    # The solver minimises weighted deviation across all 4 nutrients. With only
    # two foods (chicken and rice) it cannot hit every target tightly — it will
    # nail fat/carbs (constrained by rice) and trade off calories/protein.
    # We assert it lands within 20% of every target, which is the realistic
    # feasibility envelope for a 2-food problem.
    for nut, target in [("calories", 700), ("protein", 65), ("fat", 8), ("carbohydrates", 60)]:
        deviation = abs(achieved[nut] - target) / target
        assert deviation < 0.20, f"{nut} achieved={achieved[nut]} target={target} dev={deviation:.2%}"


def test_invalid_payload_returns_error() -> None:
    qf = QuantitiesFinder()
    bad = {"foods": [{"name": "x"}], "targets": {}}  # missing required keys
    result = json.loads(qf.handle_task(json.dumps(bad)))
    assert "error" in result, f"Expected an error key, got {result}"


def test_min_max_bounds_respected() -> None:
    qf = QuantitiesFinder()
    payload = {
        "foods": [
            {
                "name": "egg",
                "calories": 155,
                "protein": 13,
                "fat": 11,
                "carbohydrates": 1.1,
                "estimated_g": 100,
                "min_g": 50,
                "max_g": 120,
            },
            {
                "name": "oats",
                "calories": 389,
                "protein": 17,
                "fat": 7,
                "carbohydrates": 66,
                "estimated_g": 80,
                "min_g": 30,
                "max_g": 150,
            },
        ],
        "targets": {"calories": 500, "protein": 25, "fat": 15, "carbohydrates": 50},
    }
    result = json.loads(qf.handle_task(json.dumps(payload)))
    qty = result["quantities"]
    assert 50 <= qty["egg"] <= 120
    assert 30 <= qty["oats"] <= 150