]> Nutra Git (v2) - nutratech/cli.git/commitdiff
update/format/lint
authorShane Jaroch <chown_tee@proton.me>
Sun, 11 Jan 2026 11:26:32 +0000 (06:26 -0500)
committerShane Jaroch <chown_tee@proton.me>
Sun, 11 Jan 2026 11:26:32 +0000 (06:26 -0500)
ntclient/__main__.py
ntclient/argparser/__init__.py
ntclient/argparser/funcs.py
ntclient/services/calculate.py
tests/services/test_logs.py [new file with mode: 0644]

index aa58e24d3329f8573ee32f35315e738672f7da81..54353d014ceeb80bf49a27444dbeaddfa7a15088 100644 (file)
@@ -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())
index 5f261d22d1c8cab035240bd6c1b24a7096fcdefa..7a39309165144aff00308ef359309226d1ee97db 100644 (file)
@@ -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)
index 921b4614010e14e19f06173772d71aeb03a2cfe4..2d591afe82d336dd20c1e1406db79f3ddaa98d49 100644 (file)
@@ -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)
index 13e073f159115329c063871409d6e8e37aa7b18e..4a387ca5f2b91980835cb64af92d277cbdfc0628 100644 (file)
@@ -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 (file)
index 0000000..ece5a2c
--- /dev/null
@@ -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()