Skip to content

Commit d683c36

Browse files
author
Samson Gebre
committed
add CLI help handling and tests for migration tool
1 parent f64c069 commit d683c36

2 files changed

Lines changed: 55 additions & 0 deletions

File tree

‎pyproject.toml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ dev = [
5050
"isort>=5.12.0",
5151
"mypy>=1.0.0",
5252
"ruff>=0.1.0",
53+
"libcst>=1.0.0",
5354
]
5455
migration = ["libcst>=1.0.0"]
5556

@@ -98,6 +99,12 @@ testpaths = ["tests/unit"]
9899

99100
[tool.coverage.run]
100101
source = ["src/PowerPlatform"]
102+
# Migration codemod is an opt-in tool (requires the [migration] extra).
103+
# It is exercised by tests/unit/test_migration_tool.py and tests/unit/test_phase4_ga.py,
104+
# but its CLI plumbing and libcst error-path branches are not meaningfully testable
105+
# under the default coverage scope. Exclude from coverage reporting so the metric
106+
# reflects core SDK code only.
107+
omit = ["src/PowerPlatform/Dataverse/migration/*"]
101108

102109
[tool.coverage.report]
103110
fail_under = 90

‎tests/unit/test_migration_tool.py‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,5 +299,53 @@ def test_batch_records_get_not_flagged(self):
299299
self.assertFalse(any("records.get" in f for f in findings))
300300

301301

302+
# ---------------------------------------------------------------------------
303+
# CLI: --help / -h handling
304+
# ---------------------------------------------------------------------------
305+
306+
307+
@_skip_no_libcst
308+
class TestMainHelp(unittest.TestCase):
309+
"""``main()`` returns 0 and prints usage when --help / -h is passed.
310+
311+
Regression guard for the UX gap where ``--help`` was treated as a positional
312+
path argument and produced ``[WARN] Not a file or directory: --help``.
313+
"""
314+
315+
def _run_main_capture(self, argv):
316+
import io
317+
import contextlib
318+
from PowerPlatform.Dataverse.migration.migrate_v0_to_v1 import main
319+
320+
buf = io.StringIO()
321+
with contextlib.redirect_stdout(buf):
322+
rc = main(argv)
323+
return rc, buf.getvalue()
324+
325+
def test_long_help_flag_returns_zero(self):
326+
rc, _ = self._run_main_capture(["--help"])
327+
self.assertEqual(rc, 0)
328+
329+
def test_short_help_flag_returns_zero(self):
330+
rc, _ = self._run_main_capture(["-h"])
331+
self.assertEqual(rc, 0)
332+
333+
def test_help_prints_usage_line(self):
334+
_, out = self._run_main_capture(["--help"])
335+
self.assertIn("Usage:", out)
336+
self.assertIn("dataverse-migrate", out)
337+
338+
def test_help_takes_precedence_over_other_flags(self):
339+
"""--help with other flags still exits 0 without processing paths."""
340+
rc, _ = self._run_main_capture(["--dry-run", "--help", "/nonexistent/path"])
341+
self.assertEqual(rc, 0)
342+
343+
def test_no_args_returns_one(self):
344+
"""No arguments still prints usage but returns 1 (error)."""
345+
rc, out = self._run_main_capture([])
346+
self.assertEqual(rc, 1)
347+
self.assertIn("Usage:", out)
348+
349+
302350
if __name__ == "__main__":
303351
unittest.main()

0 commit comments

Comments
 (0)