From c3c457b824686f05fa3faa4d538e3284f6f8cc26 Mon Sep 17 00:00:00 2001 From: Shane Jaroch Date: Sun, 11 Jan 2026 06:26:32 -0500 Subject: [PATCH] update/format/lint --- ntclient/__main__.py | 6 +++ ntclient/argparser/__init__.py | 25 +++++++++++ ntclient/argparser/funcs.py | 2 + ntclient/services/calculate.py | 2 + tests/services/test_logs.py | 80 ++++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+) create mode 100644 tests/services/test_logs.py diff --git a/ntclient/__main__.py b/ntclient/__main__.py index aa58e24..54353d0 100644 --- a/ntclient/__main__.py +++ b/ntclient/__main__.py @@ -124,3 +124,9 @@ def main(args: list = None) -> int: # type: ignore print("Exit code: %s" % exit_code) return exit_code + + +if __name__ == "__main__": + import sys + + sys.exit(main()) diff --git a/ntclient/argparser/__init__.py b/ntclient/argparser/__init__.py index 5f261d2..7a39309 100644 --- a/ntclient/argparser/__init__.py +++ b/ntclient/argparser/__init__.py @@ -21,6 +21,7 @@ def build_subcommands(subparsers: argparse._SubParsersAction) -> None: build_subcommand_sort(subparsers) build_subcommand_analyze(subparsers) build_subcommand_day(subparsers) + build_subcommand_log(subparsers) build_subcommand_recipe(subparsers) build_subcommand_calc(subparsers) build_subcommand_bug(subparsers) @@ -390,3 +391,27 @@ def build_subcommand_bug(subparsers: argparse._SubParsersAction) -> None: "report", help="submit/report all bugs" ) bug_report_parser.set_defaults(func=parser_funcs.bugs_report) + + +# noinspection PyUnresolvedReferences,PyProtectedMember +def build_subcommand_log(subparsers: argparse._SubParsersAction) -> None: + """Log management: add, view, analyze""" + log_parser = subparsers.add_parser("log", help="manage daily food logs") + log_subparsers = log_parser.add_subparsers(dest="subcommand", required=True) + + # ADD + add_parser = log_subparsers.add_parser("add", help="add food to log") + add_parser.add_argument("food_id", type=int, help="food ID") + add_parser.add_argument("grams", type=float, help="amount in grams") + add_parser.add_argument("-d", "--date", help="date YYYY-MM-DD (default: today)") + add_parser.set_defaults(func=parser_funcs.log_add) + + # VIEW + view_parser = log_subparsers.add_parser("view", help="view log entries") + view_parser.add_argument("-d", "--date", help="date YYYY-MM-DD (default: today)") + view_parser.set_defaults(func=parser_funcs.log_view) + + # ANALYZE + anl_parser = log_subparsers.add_parser("anl", help="analyze log") + anl_parser.add_argument("-d", "--date", help="date YYYY-MM-DD (default: today)") + anl_parser.set_defaults(func=parser_funcs.log_analyze) diff --git a/ntclient/argparser/funcs.py b/ntclient/argparser/funcs.py index 921b461..2d591af 100644 --- a/ntclient/argparser/funcs.py +++ b/ntclient/argparser/funcs.py @@ -378,11 +378,13 @@ def log_add(args: argparse.Namespace) -> tuple: ntclient.services.logs.log_add(args.food_id, args.grams, args.date) return 0, [] + def log_view(args: argparse.Namespace) -> tuple: """Wrapper for log view""" ntclient.services.logs.log_view(args.date) return 0, [] + def log_analyze(args: argparse.Namespace) -> tuple: """Wrapper for log analyze""" ntclient.services.logs.log_analyze(args.date) diff --git a/ntclient/services/calculate.py b/ntclient/services/calculate.py index 13e073f..4a387ca 100644 --- a/ntclient/services/calculate.py +++ b/ntclient/services/calculate.py @@ -559,6 +559,8 @@ def calculate_scaling_multiplier( Determine the multiplier needed to scale the analysis values. """ multiplier = 1.0 + if not scale: + return multiplier if scale_mode == "kcal": current_val = analysis.get(NUTR_ID_KCAL, 0) multiplier = scale / current_val if current_val else 0 diff --git a/tests/services/test_logs.py b/tests/services/test_logs.py new file mode 100644 index 0000000..ece5a2c --- /dev/null +++ b/tests/services/test_logs.py @@ -0,0 +1,80 @@ +""" +Tests for log service. +""" + +import os +import shutil +import tempfile +import unittest +from unittest.mock import patch + +from ntclient.services.logs import log_add, log_analyze, log_view + + +class TestLogs(unittest.TestCase): + """Test class for log service""" + + def setUp(self): + """Setup temp dir""" + self.test_dir = tempfile.mkdtemp() + self.patcher = patch("ntclient.services.logs.NUTRA_HOME", self.test_dir) + self.mock_home = self.patcher.start() + + def tearDown(self): + """Cleanup""" + self.patcher.stop() + shutil.rmtree(self.test_dir) + + @patch("ntclient.services.logs.sql_food_details") + def test_log_add(self, mock_sql): + """Test adding to log""" + # Mock food exists + mock_sql.return_value = [ + (1001, 100, "Test Food", "", "", "", "", "", 0, "", 0, 0, 0, 0) + ] + + log_add(1001, 150.0, "2099-01-01") + + log_path = os.path.join(self.test_dir, "2099-01-01.csv") + self.assertTrue(os.path.exists(log_path)) + with open(log_path, "r", encoding="utf-8") as f: + content = f.read() + self.assertIn("1001,150.0", content) + + @patch("ntclient.services.logs.sql_food_details") + def test_log_add_invalid_food(self, mock_sql): + """Test adding invalid food""" + mock_sql.return_value = [] # Food not found + + # Should print error and not create file (or not append) + # Using print capture could be added, but for now check file state + log_add(9999, 150.0, "2099-01-02") + + log_path = os.path.join(self.test_dir, "2099-01-02.csv") + self.assertFalse(os.path.exists(log_path)) + + @patch("ntclient.services.logs.sql_food_details") + @patch("ntclient.services.logs.read_log") + def test_log_view(self, mock_read, mock_sql): + """Test viewing log""" + mock_read.return_value = [{"id": "1001", "grams": "150.0"}] + # Mock needs 3 elements: id, ..., name + mock_sql.return_value = [(1001, 100, "Test Food")] + + # Just ensure no exception + log_view("2099-01-01") + + @patch("ntclient.services.logs.day_analyze") + def test_log_analyze(self, mock_analyze): + """Test analyzing log""" + # Create dummy log + log_path = os.path.join(self.test_dir, "2099-01-01.csv") + with open(log_path, "w", encoding="utf-8") as f: + f.write("id,grams\n1001,100") + + log_analyze("2099-01-01") + mock_analyze.assert_called_once() + + +if __name__ == "__main__": + unittest.main() -- 2.52.0