Skip to content

Commit c3c457b

Browse files
committed
update/format/lint
1 parent 7e499ac commit c3c457b

5 files changed

Lines changed: 115 additions & 0 deletions

File tree

ntclient/__main__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,9 @@ def func(parser: argparse.Namespace) -> tuple:
124124
print("Exit code: %s" % exit_code)
125125

126126
return exit_code
127+
128+
129+
if __name__ == "__main__":
130+
import sys
131+
132+
sys.exit(main())

ntclient/argparser/__init__.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def build_subcommands(subparsers: argparse._SubParsersAction) -> None:
2121
build_subcommand_sort(subparsers)
2222
build_subcommand_analyze(subparsers)
2323
build_subcommand_day(subparsers)
24+
build_subcommand_log(subparsers)
2425
build_subcommand_recipe(subparsers)
2526
build_subcommand_calc(subparsers)
2627
build_subcommand_bug(subparsers)
@@ -390,3 +391,27 @@ def build_subcommand_bug(subparsers: argparse._SubParsersAction) -> None:
390391
"report", help="submit/report all bugs"
391392
)
392393
bug_report_parser.set_defaults(func=parser_funcs.bugs_report)
394+
395+
396+
# noinspection PyUnresolvedReferences,PyProtectedMember
397+
def build_subcommand_log(subparsers: argparse._SubParsersAction) -> None:
398+
"""Log management: add, view, analyze"""
399+
log_parser = subparsers.add_parser("log", help="manage daily food logs")
400+
log_subparsers = log_parser.add_subparsers(dest="subcommand", required=True)
401+
402+
# ADD
403+
add_parser = log_subparsers.add_parser("add", help="add food to log")
404+
add_parser.add_argument("food_id", type=int, help="food ID")
405+
add_parser.add_argument("grams", type=float, help="amount in grams")
406+
add_parser.add_argument("-d", "--date", help="date YYYY-MM-DD (default: today)")
407+
add_parser.set_defaults(func=parser_funcs.log_add)
408+
409+
# VIEW
410+
view_parser = log_subparsers.add_parser("view", help="view log entries")
411+
view_parser.add_argument("-d", "--date", help="date YYYY-MM-DD (default: today)")
412+
view_parser.set_defaults(func=parser_funcs.log_view)
413+
414+
# ANALYZE
415+
anl_parser = log_subparsers.add_parser("anl", help="analyze log")
416+
anl_parser.add_argument("-d", "--date", help="date YYYY-MM-DD (default: today)")
417+
anl_parser.set_defaults(func=parser_funcs.log_analyze)

ntclient/argparser/funcs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,11 +378,13 @@ def log_add(args: argparse.Namespace) -> tuple:
378378
ntclient.services.logs.log_add(args.food_id, args.grams, args.date)
379379
return 0, []
380380

381+
381382
def log_view(args: argparse.Namespace) -> tuple:
382383
"""Wrapper for log view"""
383384
ntclient.services.logs.log_view(args.date)
384385
return 0, []
385386

387+
386388
def log_analyze(args: argparse.Namespace) -> tuple:
387389
"""Wrapper for log analyze"""
388390
ntclient.services.logs.log_analyze(args.date)

ntclient/services/calculate.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,8 @@ def calculate_scaling_multiplier(
559559
Determine the multiplier needed to scale the analysis values.
560560
"""
561561
multiplier = 1.0
562+
if not scale:
563+
return multiplier
562564
if scale_mode == "kcal":
563565
current_val = analysis.get(NUTR_ID_KCAL, 0)
564566
multiplier = scale / current_val if current_val else 0

tests/services/test_logs.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
"""
2+
Tests for log service.
3+
"""
4+
5+
import os
6+
import shutil
7+
import tempfile
8+
import unittest
9+
from unittest.mock import patch
10+
11+
from ntclient.services.logs import log_add, log_analyze, log_view
12+
13+
14+
class TestLogs(unittest.TestCase):
15+
"""Test class for log service"""
16+
17+
def setUp(self):
18+
"""Setup temp dir"""
19+
self.test_dir = tempfile.mkdtemp()
20+
self.patcher = patch("ntclient.services.logs.NUTRA_HOME", self.test_dir)
21+
self.mock_home = self.patcher.start()
22+
23+
def tearDown(self):
24+
"""Cleanup"""
25+
self.patcher.stop()
26+
shutil.rmtree(self.test_dir)
27+
28+
@patch("ntclient.services.logs.sql_food_details")
29+
def test_log_add(self, mock_sql):
30+
"""Test adding to log"""
31+
# Mock food exists
32+
mock_sql.return_value = [
33+
(1001, 100, "Test Food", "", "", "", "", "", 0, "", 0, 0, 0, 0)
34+
]
35+
36+
log_add(1001, 150.0, "2099-01-01")
37+
38+
log_path = os.path.join(self.test_dir, "2099-01-01.csv")
39+
self.assertTrue(os.path.exists(log_path))
40+
with open(log_path, "r", encoding="utf-8") as f:
41+
content = f.read()
42+
self.assertIn("1001,150.0", content)
43+
44+
@patch("ntclient.services.logs.sql_food_details")
45+
def test_log_add_invalid_food(self, mock_sql):
46+
"""Test adding invalid food"""
47+
mock_sql.return_value = [] # Food not found
48+
49+
# Should print error and not create file (or not append)
50+
# Using print capture could be added, but for now check file state
51+
log_add(9999, 150.0, "2099-01-02")
52+
53+
log_path = os.path.join(self.test_dir, "2099-01-02.csv")
54+
self.assertFalse(os.path.exists(log_path))
55+
56+
@patch("ntclient.services.logs.sql_food_details")
57+
@patch("ntclient.services.logs.read_log")
58+
def test_log_view(self, mock_read, mock_sql):
59+
"""Test viewing log"""
60+
mock_read.return_value = [{"id": "1001", "grams": "150.0"}]
61+
# Mock needs 3 elements: id, ..., name
62+
mock_sql.return_value = [(1001, 100, "Test Food")]
63+
64+
# Just ensure no exception
65+
log_view("2099-01-01")
66+
67+
@patch("ntclient.services.logs.day_analyze")
68+
def test_log_analyze(self, mock_analyze):
69+
"""Test analyzing log"""
70+
# Create dummy log
71+
log_path = os.path.join(self.test_dir, "2099-01-01.csv")
72+
with open(log_path, "w", encoding="utf-8") as f:
73+
f.write("id,grams\n1001,100")
74+
75+
log_analyze("2099-01-01")
76+
mock_analyze.assert_called_once()
77+
78+
79+
if __name__ == "__main__":
80+
unittest.main()

0 commit comments

Comments
 (0)